【问题标题】:T4 template for PublicResXFileCodeGeneratorPublicResXFileCodeGenerator 的 T4 模板
【发布时间】:2013-01-25 10:18:08
【问题描述】:

我想要执行以下操作:在我的 Web.config 中添加一个开关,当它打开时,来自 .resx 文件的任何值都将与它来自的 .resx 文件的名称一起出现。这主要用于调试目的。

我目前的理解是,这样做的方法是创建一个自定义 T4 模板,并使用它而不是 PublicResXFileCodeGenerator

我正在尝试找到一个模板来完成PublicResXFileCodeGenerator 所做的工作,然后在此基础上进行构建。我的 Visual Studio 安装中是否有这样的模板?如果没有,我可以从网上的官方来源找到这样的模板吗?

【问题讨论】:

    标签: asp.net-mvc visual-studio t4 resx


    【解决方案1】:

    Visual Studio 使用 StronglyTypedResourceBuilder 类将 .resx 文件转换为“硬编码”资源。这就是为什么我认为 Visual Studio 安装中的某处没有类似的 T4 模板。

    您可能想要创建自己的 T4 模板。对于您的情况,我没有现成的模板,但这是我开始并替换字符串资源的默认资源构建器的方式:

    1. 从资源文件的属性网格中的 CustomTool-Property 中删除“ResXFileCodeGenerator”。
    2. 删除现有的 .Designer.cs 文件
    3. 将设置“DebugResources”添加到 web.config
    4. 在 T4 模板中打开 .resx 文件作为 XDocument(.resx 是一种 xml 格式)

      <#@ assembly name="System.Xml" #>
      <#@ assembly name="System.Xml.Linq #>
      <#@ import namespace="System.Xml.Linq #>
      
      <#
         string inputFile = System.IO.Path.GetDirectoryName(this.Host.TemplateFile)
                          + @"\MyResourceFile.resx";
         XDocument resDoc = XDocument.Load(inputFile);
      #>
      
    5. 迭代 .resx 文件中的所有元素并为资源生成属性。根据 web.config 中的设置,将资源文件名添加到返回值中。

      <#
          foreach(var dataElement in resDoc.Descendants("data")
                                           .Where(elem => elem.Attribute("type") == null)
          {
      #>
          public static string <#= dataElement.Attribute("name").Value #> {
            get {
              return ResourceManager.GetString("<#= dataElement.Attribute("name").Value #>")
                     + ((bool.Parse(ConfigurationManager.AppSettings["DebugResources"])) 
                       ? " (MyResourceFile.resx)" 
                       : String.Empty);
      <#
          }
      #>
      
    6. 生成资源类的其余部分:资源管理器(您可以从原始 Designer.cs 文件中复制它)并检查如何处理图像和其他资源类型。

    希望这个想法有所帮助。也许我可以在某个时候想出一个完整且可重复使用的 .tt。

    【讨论】:

    • 谢谢尼科。我希望有一种方法可以进入设计器文件并将所有 System.Resources.ResourceManager 替换为我可以从 ResourceManager 派生的 CustomResourceManager。也许我可以运行一个我将包含在构建中的脚本。
    • 嗯,我同意,删除所有 .designer.cs 文件可能会很耗时,而且可能会忘记删除一些文件。但是对于构建过程,ResourceManager 类位于哪个文件中并不重要。看看这里:*.com/q/14607395/1990914,这可能允许您实际替换设计器文件的内容。