如何在 T4 模板中使用 resx 资源文件

5

我不知道如何在 (.tt) T4 模板中包含资源文件 (.resx)。

我已经尝试了... 导入命名空间。

<#@ import namespace="T4TemplateResources.resx" #>

同时包括该类别。

2
你的resx文件已经编译了吗? - Daniel A. White
1
导入语句相当于在C#(VB中的import)中使用语句来隐式解析命名空间 - 它不会将任何文件带入模板。您能详细说明一下您想要实现什么吗? - GarethJ
4个回答

3

Nico的解决方案需要使用您的解决方案进行构建。

还有一种方法,无需通过读取原始resx文件来编译您的解决方案。

    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"];

请注意,如果资源不存在,则此方法缺少设计时检查,并且您不会获得本地化的值,因为您只是读取文件。这在T4模板中通常都不是强制性的要求。
以下是一个有效的片段,可从资源文件创建一个枚举。
只需确保设置fileNamefilePath的正确值即可。
<#@ 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 #>,

        <# } #>

    }

}


<#
    }
#>

2

以下是用于从资源(.resx)读取并创建包含资源 JSON 结果的 JS 文件的示例 T4 模板代码:

<#@ 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("'", "\\'")#>',
<# } #>
<# } #>
};

向Jochen van Wylick致敬: 使用T4根据.resx文件本地化JavaScript资源


0

如果您想从 T4 模板中访问 .resx 文件的资源,则应执行以下操作:

  1. 在“资源编辑器”中将资源的访问修饰符设置为“Public”。
  2. 确保项目成功构建。T4 模板只能访问输出程序集 - 因此请检查是否已更新。
  3. 在 T4 模板中引用输出程序集(您可以在此处使用 Visual Studio 宏):<#@ assembly name="$(TargetDir)\outputfile.ext" #>
  4. 在 T4 模板中导入 ResourceFile 的命名空间:<#@ import namespace="MyNamespace" #>

然后,您可以像通常一样访问资源:

<# var theResource = Resource1.TheResource; #>

0

如果您使用的是VS2010 SP1及以上版本,则有一种更简单的方法可以在不编译项目的情况下完成此操作,即使用

<#@ assembly name="$(TargetPath)" #>
<#@ import namespace="Your.Namespace.Properties" #>

复制第一行,然后在第二行中使用资源文件所在的命名空间,并像在C#中一样正常访问资源字符串。

Resources.ResourceManager.GetString("SomeKey");

或者

var key = Resources.SomeKey;

我从在T4模板中使用类中学到了这个。

希望能对某些人有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接