在编译时设置属性值

时间:2018-08-21 18:38:39

标签: c# compile-time-constant

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

[AddIn("Foobar", Version = "1.2.3.4")]
public class Foobar {
...

我通常会在项目属性的 Assembly Information 中维护版本信息-在 Assembly version File version 字段中。

enter image description here

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

这似乎是一个可能的后备选项,如果没有: Is it possible to get assembly info at compile time without reflection?

1 个答案:

答案 0 :(得分:2)

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

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

除了,将第二类设为T4模板。

类似以下内容:

    

Foobar.cs

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的复杂性,通常我建议不要使用T4,但是您可以使用。

编辑:上面链接的局部类文章适用于属性,您应该能够添加属性而无需为局部类创建元数据类。