在编译时设置属性值

Set Attribute Value at Compile Time

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

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

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

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

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

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

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

除此之外,将第二个 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 到来自其他文件的 extract/modify 文本,为您的属性提供正确的版本信息(请参见上面的一些示例代码)。

我找不到我从中提取的 SO 答案(前段时间),但我正在从构建事件运行 中转换为 运行

"%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,因为它增加了复杂性,但就这样吧。

编辑:上面链接的部分 class post 适用于属性,您应该能够添加属性而无需为部分 class 创建元数据 class .