T4命名空间和类型解析

时间:2011-02-05 18:58:32

标签: c# asp.net-mvc resources t4

我正在尝试创建T4模板,它将获取我的应用程序全局资源,循环遍历静态属性并创建一个具有const string属性的静态类,因此我可以将资源名称设为{{1使用强类型。

这就是我现在所拥有的:

string

问题是它无法在<#@ template debug="true" hostSpecific="true" #> <#@ include file="EF.Utility.CS.ttinclude"#> <#@ output extension=".cs"#> <#@ import namespace="System" #> <#@ import namespace="System.IO" #> <#@ import namespace="System.Diagnostics" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Collections" #> <#@ import namespace="System.Collections.Generic" #> <# CodeGenerationTools code = new CodeGenerationTools(this); MetadataLoader loader = new MetadataLoader(this); CodeRegion region = new CodeRegion(this, 1); MetadataTools ef = new MetadataTools(this); string namespaceName = code.VsNamespaceSuggestion(); if (!String.IsNullOrEmpty(namespaceName)) { #> namespace <#=code.EscapeNamespace(namespaceName)#> { <# PushIndent(CodeRegion.GetIndent(1)); } #> public static class ResourceStrings { <# var props = typeof(Resources).GetProperties(BindingFlags.Static); foreach (var prop in props) { #> public const string <#= prop.Name #> = "<#= prop.Name #>"; <# } #> } <# if (!String.IsNullOrEmpty(namespaceName)) { PopIndent(); #> } <# } #> <#+ // Insert any template procedures here #> 中找到Resources命名空间。 typeof()命名空间是Localize.designer.cs文件的名称空间(Localize.resx的自动生成文件)。

我在这里缺少什么?

3 个答案:

答案 0 :(得分:5)

我刚才有类似的想法。我想为我的用户设置创建一个带有const字符串值的静态类,以便在Windows窗体绑定中使用强类型而不是字符串:

this.textBox1.DataBindings.Add("Text", Properties.Settings.Default, Properties.Settings.PropertyNames.SomeStringValue);

但是,我发现t4模板无法访问当前项目的类型。 您必须使用

加载文件
<#@ assembly name="$(TargetPath)" #>

但是,如果您这样做并重新生成模板,则不会重建项目,因为除非您关闭visual studio,否则文件正在使用中。

长话短说,

我放弃了这种方法,现在我自己读取app.config文件以获取我需要的数据。 应该很容易修改以改为阅读Resources.xml文件。

<#@ template debug="true" hostspecific="true" language="C#" #>
<#@ output extension=".cs" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="System.Xml" #>
<#@ assembly name="System.Xml.Linq" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Xml.Linq" #>

<#
var xmlFile = Path.Combine(Path.GetDirectoryName(Host.TemplateFile), "..", "app.config");
var query = from x in XElement.Load(xmlFile).Element("userSettings").Element("Your.Namespace.Properties.Settings").Elements("setting")
            select x;
#>

namespace Your.Namespace.Properties
{
    public sealed partial class Settings
    {
        public static class PropertyNames
        {

        <# foreach (var item in query) { #>
        public static readonly string <#=item.Attribute("name").Value#> = @"<#=item.Attribute("name").Value#>";
        <# } #>

        }
    }
}

答案 1 :(得分:2)

尝试使用T4Toolbox和Volatile Assembly指令。

<#@ VolatileAssembly processor="T4Toolbox.VolatileAssemblyProcessor"
Name="<Your assembly fully qualified name that you are concerned about locking but need a self reference to>"#>

它将创建程序集的卷影副本以用于T4。

您需要下载并安装T4Toolbox才能实现此目的。

http://t4toolbox.codeplex.com/

答案 2 :(得分:2)

您可以使用以下命令获取对当前命名空间的引用:

<#+
    // other template code here...
    static string CurrentNamespace = System.Runtime.Remoting.Messaging.CallContext.LogicalGetData("NamespaceHint").ToString();

并在模板输出中使用它,如下所示:

namespace <#=CurrentNamespace #>
{
    public static class MyGenerateClass
    {
       // other generated code here...