How to use a resx resource file in a T4 template

后端 未结 4 1057
不思量自难忘°
不思量自难忘° 2021-01-03 11:24

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         


        
相关标签:
4条回答
  • 2021-01-03 11:57

    If you want to access the resources of a .resx-File from within a T4 template, this is how you would do it:

    1. In the Resource Editor set the Access Modifier for the resources to "Public".
    2. Make sure your project builds successfully. The t4 template can only access the output assembly - so check if it's up to date.
    3. Reference the output assembly in the T4 template (you can use Visual Studio Macros here): <#@ assembly name="$(TargetDir)\outputfile.ext" #>
    4. Import the namespace of the ResourceFile in the T4 template <#@ import namespace="MyNamespace" #>

    Then you can access the resources as usually:

    <# var theResource = Resource1.TheResource; #>
    
    0 讨论(0)
  • 2021-01-03 12:04

    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

    0 讨论(0)
  • 2021-01-03 12:06

    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

    0 讨论(0)
  • 2021-01-03 12:22

    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 #>,
    
            <# } #>
    
        }
    
    }
    
    
    <#
        }
    #>
    
    0 讨论(0)
提交回复
热议问题