Skip to content

Instantly share code, notes, and snippets.

@thomaslevesque
Last active February 5, 2021 15:06
Show Gist options
  • Save thomaslevesque/5497578 to your computer and use it in GitHub Desktop.
Save thomaslevesque/5497578 to your computer and use it in GitHub Desktop.
Generates a strongly typed wrapper for a resource file, compatible with the Portable Class Library. Just drop this T4 template in your project, with the same base name as a .resx file in the same folder (e.g. Strings.tt for Strings.resx)
<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="System.Xml" #>
<#@ assembly name="System.Xml.Linq" #>
<#@ assembly name="EnvDTE" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Globalization" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Xml.Linq" #>
<#@ import namespace="EnvDTE" #>
<#@ output extension=".cs" #>
<#
var project = FindProject();
string className = Path.GetFileNameWithoutExtension(Host.TemplateFile);
string resourceFileName = className + ".resx";
string resourcesDir = Path.GetDirectoryName(Host.TemplateFile);
string projectDir = Path.GetDirectoryName(project.FullName);
string relativePath = resourcesDir.Substring(projectDir.Length);
string resourcesFile = Host.ResolvePath(resourceFileName);
string resourceNamespace = project.Name;
if (!string.IsNullOrEmpty(relativePath))
resourceNamespace += relativePath.Replace('\\', '.');
string baseName = string.Format("{0}.{1}", resourceNamespace, className);
var doc = XDocument.Load(resourcesFile);
var entries =
from d in doc.Root.Elements("data")
select new
{
Name = d.Attribute("name").Value,
Value = d.Element("value").Value
};
#>
using System;
using System.Globalization;
using System.Reflection;
using System.Resources;
namespace <#= resourceNamespace #>
{
public static class <#= className #>
{
private static readonly Lazy<ResourceManager> _resourceManager =
new Lazy<ResourceManager>(() => new ResourceManager("<#= baseName #>", typeof(<#= className #>).GetTypeInfo().Assembly));
public static ResourceManager ResourceManager
{
get { return _resourceManager.Value; }
}
public static CultureInfo Culture { get; set; }
<# foreach(var entry in entries) { #>
/// <summary>
/// Returns a string similar to '<#= Ellipsis(entry.Value, 50) #>'
/// </summary>
public static string <#= entry.Name #>
{
get { return ResourceManager.GetString("<#= entry.Name #>", Culture); }
}
<# } #>
}
}
<#+
static string Ellipsis(string s, int maxLength)
{
if (s.Length <= maxLength)
return s;
return s.Substring(0, maxLength) + "...";
}
Project FindProject()
{
IServiceProvider serviceProvider = (IServiceProvider)Host;
DTE dte = (DTE)serviceProvider.GetService(typeof(DTE));
string templateFileName = Host.TemplateFile;
var item = dte.Solution.FindProjectItem(Host.TemplateFile);
if (item != null && item.ContainingProject != null)
return item.ContainingProject;
throw new InvalidOperationException("Can't find project name");
}
#>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment