📝

C# Source Generator で GeneratedCodeAttribute のバージョン番号を自動でふる

2021/03/26に公開

C# Source Generatorで生成するクラスにはGeneratedCodeAttributeをつけたい。こいつを付けといてあげればコードカバレッジツールが計測対象に入れないとか、周辺ツールが便宜を図ってくれる。

GeneratedCodeAttribute以外にもCompilerGeneratedAttributeとか、<auto-generated> XMLコメントとかもあるとうれしい。

で、このGeneratedCodeAttributeのコンストラクタ引数が2つあって、1つ目がツール名、2つ目がツールバージョンになってるんやけど、2つ目のツールバージョンが微妙。直接書くとバージョンアップの時に更新を忘れてしまいそう。
ということで、MinVerThisAssembly。詳細はリンク先へ。

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>

この設定されたAssemblyMetadataAttributeApplicationVersionの値をThisAssemblyMetadataで取得する。私はコード書き出しに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