【问题标题】:How to use a resx resource file in a T4 template如何在 T4 模板中使用 resx 资源文件
【发布时间】:2013-04-08 17:32:27
【问题描述】:

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

到目前为止我已经尝试过...正在导入命名空间

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

还包括类

【问题讨论】:

  • 你的 resx 编译了吗?
  • import 语句将相当于 using 语句添加到 C#(在 VB 中导入)以隐式解析命名空间 - 它不会将任何文件带入模板。您能否详细说明您想要实现的目标?

标签: c# t4 resx


【解决方案1】:

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 致敬: Using T4 for localizing JavaScript resources based on .resx files

    【讨论】:

      【解决方案3】:

      如果您想从 T4 模板中访问 .resx 文件的资源,您可以这样做:

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

      然后你就可以像往常一样访问资源了:

      <# var theResource = Resource1.TheResource; #>
      

      【讨论】:

        【解决方案4】:

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

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

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

        Resources.ResourceManager.GetString("SomeKey");
        

        var key = Resources.SomeKey;
        

        我是从Use class inside a T4 template那里学到的

        希望对某人有所帮助

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-03-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-04-09
          相关资源
          最近更新 更多