Now that we have the new project system, and we can define common assembly info in our .csproj
, we can say good-bye to AssemblyInfo.cs
, well, I still see these left around for general assembly attributes.
For example it is quite common to see an InternalsVisibileTo.cs
file these days, instead of AssemblyInfo.cs
, see here for an example.
However what if you want to add your own assembly attribute with a value you want to pass in as an MSBuild property? For example, an AssemblyMetadataAttribute
that contains a git commit hash?
Well, we are in luck, there is an AssemblyAttribute
item we can add to our ItemGroup! If we had a property named CommitHash
we could write the following:
<AssemblyAttribute Include="System.Reflection.AssemblyMetadataAttribute" Condition="$(CommitHash) != ''" >
<_Parameter1>CommitHash</_Parameter1>
<_Parameter2>$(CommitHash)</_Parameter2>
</AssemblyAttribute>
Great! One last thing, we need to say when this is going to happen, and that is before CoreGenerateAssemblyInfo
, so:
<Target Name="AddGitMetadaAssemblyAttributes"
BeforeTargets="CoreGenerateAssemblyInfo">
<ItemGroup>
<AssemblyAttribute Include="System.Reflection.AssemblyMetadataAttribute" Condition="$(CommitHash) != ''" >
<_Parameter1>CommitHash</_Parameter1>
<_Parameter2>$(CommitHash)</_Parameter2>
</AssemblyAttribute>
</ItemGroup>
</Target>
Cool. But wait! It doesn't always work. Sometimes when I do a build, the value doesn't change. What gives?
So it turns out in .NET SDK 2 and up, there are lots of measures to improve performance, one of which is the <AssemblyName>.AssemblyInfoInputs.cache
file, which appears in the obj
folder, and just contains a hash of the AssemblyInfo
inputs as you'd expect.
The hash is calculated internally only by the _Parameter1
values, so in our example where we put the varying data in _Parameter2
, this doesn't bust the cache. We can see the logic for this here in CreateGeneratedAssemblyInfoInputsCacheFile
.
As a hacky workaround, we can temporarily add our values to _Parameter1
then remove them after the hash is generated. Like this:
<Target Name="GitMetadataAssemblyInfoCacheFileFix"
BeforeTargets="CreateGeneratedAssemblyInfoInputsCacheFile" >
<ItemGroup>
<AssemblyAttribute Include="TemporaryAdditionalHashItem" Condition=" $(CommitHash) != '' ">
<_Parameter1>$(CommitHash)</_Parameter1>
</AssemblyAttribute>
</ItemGroup>
</Target>
<Target Name="CleanupTemporaryAdditionalHashItem"
AfterTargets="CreateGeneratedAssemblyInfoInputsCacheFile;AddGitMetadaAssemblyAttributes" >
<ItemGroup>
<AssemblyAttribute Remove="TemporaryAdditionalHashItem" />
</ItemGroup>
</Target>
Now we recompile whenever there is a change to our added value. For the end result, see here.
UPDATE: In the upcoming SDK at the time of writing (2.1.300), this hack is no longer required as @natemcmaster has fixed it here. Hurray!
Top comments (0)