C# Source Generator で GeneratedCodeAttribute のバージョン番号を自動でふる
C# Source Generatorで生成するクラスにはGeneratedCodeAttributeをつけたい。こいつを付けといてあげればコードカバレッジツールが計測対象に入れないとか、周辺ツールが便宜を図ってくれる。
GeneratedCodeAttribute以外にもCompilerGeneratedAttributeとか、<auto-generated>
XMLコメントとかもあるとうれしい。
で、このGeneratedCodeAttributeのコンストラクタ引数が2つあって、1つ目がツール名、2つ目がツールバージョンになってるんやけど、2つ目のツールバージョンが微妙。直接書くとバージョンアップの時に更新を忘れてしまいそう。
ということで、MinVerとThisAssembly。詳細はリンク先へ。
MinVerで振ったバージョン番号をMSBuild上のMinVerVersion
って変数でとれるようになっている。なので、MinVerが実行されたあとのタスクで、AssemblyMetadataAttribute
にその値を設定する。次の例ではApplicationVersion
って名前で値を設定しています。
<Target Name="XXXXX" AfterTargets="MinVer"> <!--MinVerのあとに動くよって指定-->
<ItemGroup>
<!--AssembleyMetadata属性をApplicationNameってキー名で、MinVerVersinの値で作ってねって設定-->
<AssemblyAttribute Include="System.Reflection.AssemblyMetadataAttribute">
<_Parameter1>ApplicationVersion</_Parameter1>
<_Parameter2>$(MinVerVersion)</_Parameter2>
</AssemblyAttribute>
</ItemGroup>
</Target>
この設定されたAssemblyMetadataAttribute
のApplicationVersion
の値をThisAssemblyのMetadataで取得する。私はコード書き出しにT4使うことが多いので、T4での例。
namespace <#= this.Model.NamespaceName #>
{
[CompilerGenerated]
[GeneratedCode("MySourceGenerator", "<#= ThisAssembly.Metadata.ApplicationVersion #>")]
<#= this.Model.ClassModifer #> static partial class <#= this.Model.ClassName #>
{
これでソースジェネレーターをnugetで公開するときのバージョンをMinVerで設定していれば、なにもしなくてもちゃんと一致するからメデタシメデタシ。
まぁ、実際はMinVerじゃなくても他のもので、最終的にThisAssemblyに繋げられれば何でもOKなんですが。
Discussion