I cant figure out how to include the resource file (.resx) in the (.tt) T4 template.
I tried so far... Importing the namespace
<#@ import names
If you want to access the resources of a .resx-File from within a T4 template, this is how you would do it:
<#@ assembly name="$(TargetDir)\outputfile.ext" #>
<#@ import namespace="MyNamespace" #>
Then you can access the resources as usually:
<# var theResource = Resource1.TheResource; #>
There is an easier way to do this without compiling your project if you are using VS2010 SP1 and above, by using
<#@ assembly name="$(TargetPath)" #>
<#@ import namespace="Your.Namespace.Properties" #>
Copy the first line as it is, and in the second line use the namespace where the Resource file resides and access the resource strings normally as you would in c#
Resources.ResourceManager.GetString("SomeKey");
or
var key = Resources.SomeKey;
I learnt this from Use class inside a T4 template
Hope it helps somebody
Sample T4 template code for reading from the Resources (.resx) and creating a JS file with the JSON result for the resources:
<#@ template debug="true" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="$(TargetPath)" #>
<#@ assembly name="System.Windows.Forms" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Resources" #>
<#@ import namespace="System.Collections" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".js" #>
<#
var path = Path.GetDirectoryName(Host.TemplateFile);
var resourceNames = new string[1]
{
"Resources"
};
#>
var $.Resources = {
<# foreach ( var name in resourceNames ) {
var localeFile = Host.ResolvePath(path + "\\" + name + ".resx");
ResXResourceSet jpResxSet = new ResXResourceSet(localeFile);
#>
<# foreach (DictionaryEntry item in jpResxSet) { #>
'<#=item.Key.ToString()#>' : '<#= ("" + item.Value).Replace("\r\n", string.Empty).Replace("'", "\\'")#>',
<# } #>
<# } #>
};
Kudos to Jochen van Wylick: Using T4 for localizing JavaScript resources based on .resx files
Nico's solution requires your solution to build.
There is another way, without needing to compile your solution by reading the raw resx file.
var fileName = "CustomResource.resx";
var filePath = Path.Combine(Path.GetDirectoryName(this.Host.ResolvePath("")), "WindowsFormsApplication1", fileName);
var reader = new ResXResourceReader(filePath);
var values = reader.Cast<DictionaryEntry>().ToDictionary(x => x.Key, y => y.Value);
// this is how you would acces the resources
var value = values["entry"];
You should be aware that this method lacks design time checking if the resource does not exist and you don't get localized values because you are just reading a file. Both are often not mandatory withing T4 templates
Here is a working snipped that creates an enum from a resource file.
Just make sure you use set the right values for fileName
and filePath
<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ output extension=".cs" #>
<#@ assembly name="System.Windows.Forms" #>
<#@ import namespace="System.Resources" #>
<#@ import namespace="System.Collections" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.ComponentModel.Design" #>
<#
var nameSpace = "WindowsFormsApplication1";
var enumName = "CustomEnum";
var fileName = "CustomResource.resx";
var filePath = Path.Combine(Path.GetDirectoryName(this.Host.ResolvePath("")), "WindowsFormsApplication10", fileName);
using (var reader = new ResXResourceReader(filePath))
{
reader.UseResXDataNodes = true;
#>
namespace <#=nameSpace#>
{
public enum <#=enumName#>
{
Undefined,
<# foreach(DictionaryEntry entry in reader) {
var name = entry.Key;
var node = (ResXDataNode)entry.Value;
var value = node.GetValue((ITypeResolutionService) null);
var comment = node.Comment;
var summary = value;
if (!String.IsNullOrEmpty(comment)) summary += " - " + comment;
#>
/// <summary>
/// <#= summary #>
/// </summary>
<#= name #>,
<# } #>
}
}
<#
}
#>