AssemblyInfo.cs中的模板化值?或者引用AssemblyInfo.cs中的其他值?

时间:2015-01-27 22:39:26

标签: c# templates assemblyinfo

我有几个C#项目在某种意义上是一个单元。有几种常见的AssemblyInfo属性可以在它们之间共享(例如公司名称)。所以我创建了一个包含所有项目的共享文件,包含(例如)AssemblyCompany

[assembly: AssemblyCompany("Acme Inc.")]

我从每个项目的各个AssemblyInfo.cs中删除了相应的属性。

这一切都运作良好,但我想在一个案例中更进一步:版权。出版的第一年因项目而异,因此他们确实应该有不同的版权字符串。所以我想在共享文件中做这样的事情:

[assembly: AssemblyCopyright(string.Format("Copyright {$0} Acme Inc.", Acme.AssemblyInfo.FirstPublicationYear)]

然后让每个项目定义自己的特定Acme.AssemblyInfo.FirstPublicationYear

我在黑暗中拍摄了几张不同的镜头。首先,我只是尝试在项目的AssemblyInfo.cs中的静态类中定义一个const:

namespace Acme
{
    public static class AssemblyInfo
    {
        public const int FirstPublicationYear = 2015;
    }
}

这导致错误"属性参数必须是属性参数类型"的常量表达式,typeof表达式或数组创建表达式。所以我尝试制作一个属性类:

namespace Acme
{
    using System;

    [AttributeUsage(AttributeTargets.Assembly)]
    public class FirstPublicationYearAttribute : Attribute
    {
        private int year;

        public FirstPublicationYearAttribute(int year)
        {
            this.year = year;
        }
    }
}

将该属性添加到单个项目的AssemblyInfo.cs:

[assembly: Acme.FirstPublicationYear(2015)]

但我不确定如何(或者即使我可以)适当地更改共享属性文件中的AssemblyCopyright行。我尝试了几种无法奏效的方法。第一:

[assembly: AssemblyCopyright(string.Format("Copyright © {$0} Acme, Inc.", Acme.FirstPublicationYear))]

...告诉我FirstPublicationYear在命名空间Acme中不存在。所以我想也许我会让它看起来更像一个属性:

[assembly: AssemblyCopyright(string.Format("Copyright © {$0} Acme, Inc.", [assembly: Acme.FirstPublicationYear]))]

...告诉我"无效的表达术语' ['"。

有没有办法完成我在这里尝试做的事情?感谢。

2 个答案:

答案 0 :(得分:1)

不要使用string.Format,只需尝试连接它:

"Copyright" + Acme.AssemblyInfo.FirstPublicationYear + "Acme Inc."

编译器将能够使编译时间保持不变。

答案 1 :(得分:0)

使用代码完成此没有好办法。原因是Attributes 必须具有编译时值以正确地将数据输出到结果文件,因此无法从部件逻辑地构建它们,因为根据定义,该构建是运行 - 时间,而非编译时间,操作。

编辑:事实证明,即使在编译时,也可以使用+运算符连接字符串,只要连接的所有字符串本身都是常量。见弗兰克的答案。

但是,因为所有这些值都来自单个共享文件,所以 可以通过编写预构建批处理文件来完成此操作。我已经将生产代码实现为prebuild步骤中的简单调用,所述帮助程序是用C#编写的。只要您的仓库忽略输出文件(通常是AssemblyInfo.cs)(如果您不使用仓库,请切换到一个),您就可以了依赖于prebuild生成的文件,然后由编译器找到,即使它实际上没有被复制下来。