Wednesday, August 25, 2021

SDK Project attributes

The newer SDK-style project files (*.csproj) do not support all of the Assembly attributes that could be used in older project files. A simple example is the AssemblyTrademarkAttribute. There is no <Trademark> element defined in the new projects. Arbitrary attributes can however be added like this sample:

<ItemGroup>
    <AssemblyAttribute Include="System.Reflection.AssemblyTrademarkAttribute">
      <_Parameter1>My Trademark</_Parameter1>
    </AssemblyAttribute>
</ItemGroup>

It's a bit ugly and I can't find formal documentation of the elements, but it works fine. Some people are using this technique to add InternalsVisibleTo attributes to their assemblies without the need to manually add an AssemblyInfo.cs file to their project.

An interesting trick is create your own Attribute with a string property and constructor parameter, then use it like this:

<ItemGroup>
    <AssemblyAttribute Include="MyCompany.AssemblyBuildTimeAttribute">
      <_Parameter1>$([System.DateTime]::UtcNow.ToString("yyyy-MM-dd HH:mm:ss"))</_Parameter1>
    </AssemblyAttribute>
</ItemGroup>

A couple of weeks later I realised that only attributes with string constructor arguments can be used this way. If you try to add CLSCompliant for example, you'll find there's no way to pass a bool value to it. Searches hint that this behaviour is expected and suggest you put extra assembly attributes in a separate cs file in the traditional way.

October 2023 Update

You can now create non-string attributes. I found this GitHub issue: https://github.com/dotnet/msbuild/issues/2281. I also read last week in the msbuild documentation that the fix has been released, but I can't find it... It's something to do with _Parameter1_IsLiteral. To be continued...


No comments:

Post a Comment