C# のアセンブリ情報はAssemblyInfo.csによって制御されています。 .NET Coreでいくぶん取り扱いが変わったものの基本は一緒です。
たびたび忘れるので、どのように取り扱いが変わったのか制御方法をメモしておきます。
- 概要
- Microsoft.NET.GenerateAssemblyInfo.targets
- AssemblyInfo の自動生成をなぜ制御するのか
- AssemblyInfoの自動生成を止める
- AssemblyInfo の特定の属性の生成を止める
概要
- .NET CoreでAssemblyInfo.csはビルド時に自動生成される
- csprojにGenerateAssemblyInfoを指定することで自動生成自体を止めたり、GenerateAssemblyXxxxxAttributeを指定することで特定属性の出力を止めることができる
- 出力を上書きたいときは、上書きたい属性だけ制御するようにして予期せぬ副作用は回避しましょう
Microsoft.NET.GenerateAssemblyInfo.targets
AssemblyInfoは、.NET FrameworkまではProperties/AssemblyInfo.csとして存在していましたが、.NET Core SDKベースのcsprojではビルド時に自動生成されます。
この自動生成を制御しているMSBuildのタスクMicrosoft.NET.GenerateAssemblyInfo.targetsを見つつどのように行うか見ていきましょう。
sdk/Microsoft.NET.GenerateAssemblyInfo.targets at master · dotnet/sdk
AssemblyInfo の自動生成をなぜ制御するのか
自前でAssemblyInfoを生成しようとしたときに、属性が重複してビルドできなくなるためです。
例えば、.NET Coreの適当なプロジェクトを作って次のようにアセンブリのバージョンを任意の値で制御しようとするとエラーが起こります。
https://gist.github.com/guitarrapc/6d01953b210e167ed78c41b3a20f173e
エラーは次の通りです。
Error CS0579 Duplicate 'System.Reflection.AssemblyVersionAttribute' attribute
このような時に、AssemblyInfoの出力を制御したくなります。
AssemblyInfoの自動生成を止める
dotnet coreのプロジェクトでビルドをすると、objフォルダの中にASSEMBLYNAME.AssemblyInfo.csが自動生成されます。
ASSEMBLYNAMEは、デフォルトではプロジェクト名ですがご存知の通り指定もできます。(ここでは省きます)
先ほどのMicrosoft.NET.GenerateAssemblyInfo.targetsから、次の属性で制御されていることがわかります。
<PropertyGroup Condition="'$(GenerateAssemblyInfo)' == 'true'">
AssemblyInfoの自動生成を止めたいプロジェクトのcsprojに次の要素を書くことで、objに生成されなくなります。
<PropertyGroup> <GenerateAssemblyInfo>false</GenerateAssemblyInfo> </PropertyGroup>
例えば先ほどのConsoleアプリのcsprojを編集してみましょう。(上:編集前Before.csproj / 下:編集後After.csproj)
https://gist.github.com/guitarrapc/ad8184dd3738a7c9a13b09a8a17d3af3
これでAssebly属性の重複によるビルドエラーが解消して、ビルドができるようになりました。 先ほどまであったConsoleApp2.AssemblyInfo.csがobjフォルダに生成されなくなったことが確認できます。

ただし、AssemblyInfoの自動生成を止めると副作用が大きいため推奨しません。
特に、ASP.NET Coreや .NET CoreでUserSecretsを使っている場合、UserSecretsが機能しなくなります。UserSecretsが実行時にsecretのパスを参照するとき、Secret IdはAssemblyInfoへビルド時に埋め込むようためで、自動生成を止めるとUserSecretsのIdも参照できなくなります。
AssemblyInfo の特定の属性の生成を止める
先ほどのようにただバージョンを指定したものにするなら、AssemblyInfoは生成するけど、特定の属性をとめるほうが副作用はありません。
これは先ほどのMicrosoft.NET.GenerateAssemblyInfo.targetsから、次の属性で制御されていることがわかります。
https://gist.github.com/guitarrapc/ba3dbcdaae9ddc79264660583f5d4d5f
例えば、今回のようなAssemblyVersion属性の重複なら、次の要素をcsprojに追加しましょう。
<PropertyGroup> <GenerateAssemblyVersionAttribute>false</GenerateAssemblyVersionAttribute> </PropertyGroup>
これでAssemblyInfoの生成自体をとめることなくビルドできるようになります。
objに自動生成されたConsoleApp2.AssemblyInfo.csを見てみると、意図したとおり属性で指定したバージョンが埋め込まれていることがわかります。
https://gist.github.com/guitarrapc/adf8aff6b708732ad92194eb6bd55b9e