代码之家  ›  专栏  ›  技术社区  ›  jhilgeman

在编译时设置属性值

  •  3
  • jhilgeman  · 技术社区  · 8 年前

    我有一个程序集使用System.AddIn程序集属性:

    [addin(“foobar”,version=“1.2.3.4”)]
    公共类foobar{
    …
    < /代码> 
    
    

    我通常在项目属性中的程序集信息中维护版本信息-在程序集版本中和文件版本中字段中。

    是否有任何可以用来保持属性版本与程序集或文件版本同步的魔力常量或编译时常量?

    这看起来是一个可能的回退选项,如果不是: Is possible to get assembly info at compile time without reflection?

    我通常在程序集信息在项目属性中-在程序集版本和文件版本领域。

    enter image description here

    是否有任何可以用来保持属性版本与程序集或文件版本同步的魔力常量或编译时常量?

    这看起来是一个可能的回退选项,如果不是: Is it possible to get assembly info at compile time without reflection?

    1 回复  |  直到 8 年前
        1
  •  2
  •   BurnsBA svenningsson    8 年前

    好吧,这是一个复杂的解决方法。

    将您的类改为部分类。把所有的逻辑放到一个主文件中。在单独的文件中,用所需的属性来修饰类。见 Can I define properties in partial classes, then mark them with attributes in another partial class?

    但是,将第二个类设为T4模板。

    如下所示:

    福巴

    public partial class Foobar {
        // regular code
        ...
    }
    

    foobarattributes.tt(此处语法突出显示错误)

    <#@ template debug="true" hostspecific="true" language="C#" #>
    <#@ output extension=".cs" #>
    <#@ import namespace="System.IO" #>
    <#@ import namespace="System.Text.RegularExpressions" #>
    <#
    int major = 1;
    int minor = 0;
    int revision = 1;
    int build = 1;
    
        try
        {
            // Code here is copied from a template in the Properties 
            // folder that auto-increments the build version, so that's the file location  
            string currentDirectory = Path.GetDirectoryName(Host.TemplateFile);
            string assemblyInfo = File.ReadAllText(Path.Combine(currentDirectory,"AssemblyInfo.cs"));
            Regex pattern = new Regex("AssemblyVersion\\(\"\\d+\\.\\d+\\.(?<revision>\\d+)\\.(?<build>\\d+)\"\\)");
            MatchCollection matches = pattern.Matches(assemblyInfo);
            revision = Convert.ToInt32(matches[0].Groups["revision"].Value);
            build = Convert.ToInt32(matches[0].Groups["build"].Value) + (incBuild?1:0);
        }
        catch(Exception)
        { }
    #>
    [AddIn("Foobar", Version = "<#= this.major #>.<#= this.minor #>.<#= this.revision #>.<#= this.build #>")]
    public partial class Foobar
    {
        // ...
    }
    

    设置事件以在生成时编译模板。现在,您可以将C代码写入T4中,以从其他文件中提取/修改文本,从而为属性提供正确的版本信息(请参见上面的示例代码)。

    我找不到我从中提取的答案,但我正在从生成事件中运行转换。

    "%CommonProgramFiles(x86)%\microsoft shared\TextTemplating\$(VisualStudioVersion)\TextTransform.exe" -a !!build!true "$(ProjectDir)Properties\AssemblyInfo.tt"
    

    但见 Get Visual Studio to run a T4 Template on every build 对于一些类似的想法。

    我不确定这是否是正确的解决方案,一般来说,我会建议不要使用T4,因为它增加了复杂性,但现在可以了。

    编辑:上面链接的分部类post应用于属性,您应该只能够添加属性而不为分部类创建元数据类。