ReSharper.ExportAnnotations.Core
1.2.0
See the version list below for details.
dotnet add package ReSharper.ExportAnnotations.Core --version 1.2.0
NuGet\Install-Package ReSharper.ExportAnnotations.Core -Version 1.2.0
<PackageReference Include="ReSharper.ExportAnnotations.Core" Version="1.2.0" />
paket add ReSharper.ExportAnnotations.Core --version 1.2.0
#r "nuget: ReSharper.ExportAnnotations.Core, 1.2.0"
// Install ReSharper.ExportAnnotations.Core as a Cake Addin #addin nuget:?package=ReSharper.ExportAnnotations.Core&version=1.2.0 // Install ReSharper.ExportAnnotations.Core as a Cake Tool #tool nuget:?package=ReSharper.ExportAnnotations.Core&version=1.2.0
ReSharper.ExportAnnotations
If you find this project useful, please :star: star it. Thank you!
The problem
Let's say you have written a wonderful .NET library that you want to share with the whole world, or just among your own projects.
Let's also say that you, just like me, use ReSharper for static code analysis, and have constellated your library's code with those nice annotations: [NotNull]
, [CanBeNull]
, [ItemNotNull]
, [InstantHandle]
, etc. etc. (the complete list is here in case you're curious).
Code annotations are cool, but once you've wrapped your library in a nice NuGet package, how can ReSharper know about the annotations it contains? So far, your options were:
- Either reference the
JetBrains.Annotations
package in your NuGet package, making it a transient dependency for all projects using your library, and ending up withJetBrains.Annotations.dll
in your executable directory, where it definitely serves no purpose at all... - ...or you can embed code annotation declarations in your cource code. For each project. If you call this an option, that is. I personally do not.
- You may also not define the
JETBRAINS_ANNOTATIONS
constant when you build your package, thus giving up annotations completely and making code analysis harder and less precise in dependent projects.
Let's be honest: all three options above suck. Either you have to distribute an utterly useless assembly, or you end up with more code to build and maintain, or you just give up a big part of what makes ReSharper worth its price (not to mention loading time).
A fourth option would be to use Fody with the JetBrainsAnnotations.Fody plugin, that does exactly what this task does. Which is fine, if you already use Fody; otherwise, you have to create a configuration file for it, then reference two packages (Fody itself and the plugin). I've never tried it: it most probably works fine. I was looking for a simpler solution, though, so here it is.
The solution
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<ExportJetBrainsAnnotations>true</ExportJetBrainsAnnotations>
<StripJetBrainsAnnotations>true</StripJetBrainsAnnotations>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="2019.1.3" PrivateAssets="All" />
<PackageReference Include="ReSharper.ExportAnnotations.Task" Version="1.0.0" PrivateAssets="All" />
</ItemGroup>
</Project>
That's all you need to do. Here's what happens when you build your project:
- the
JETBRAINS_ANNOTATIONS
constant is automatically defined; - just after the compiler runs, your compiled assembly is scanned for ReSharper annotations;
- all annotations of exposed types and members of exposed types are exported in an external annotations file;
- the external annotations file is part of the build output, so it is also included in your NuGet package;
- code annotations attributes, as well as the reference to
JetBrains.Annotations.dll
, are stripped from your assembly.
Now, when you reference your library from another project, ReSharper will automatically load annotations from the external annotations file and use them just as if they were compiled into your assembly!
Compatibility
In short, if you use MSBuild, you can use this task.
.NET Framework | Mono | .NET Core | |
---|---|---|---|
Windows | Yes | Yes | Yes |
OS/X | (n/a) | Yes | Yes |
Linux | (n/a) | Yes | Yes |
Caveats
Building under Non-Windows operating systems
If you build under a non-Windows operating system, the process of stripping annotations will also strip away debug symbols from your assembly. This is a limitation of the Mono.Cecil library.
You may want to only strip annotations in Release mode. Be aware that this way your debug mode assembly will still reference JetBrains.Annotations.dll
, which will become a transient dependency.
For example, given the project file above, to strip annotations only in Release mode you can add the following lines at the bottom of the file, just before the </Project>
line:
<PropertyGroup Condition="'$(Configuration)' != 'Release'">
<StripJetBrainsAnnotations>false</StripJetBrainsAnnotations>
</PropertyGroup>
<ItemGroup Condition="'$(Configuration)' != 'Release'">
<PackageReference Update="JetBrains.Annotations" PrivateAssets="" />
</ItemGroup>
Supported project types
This task has been tested on .csproj
project files, both "old-style" (no SDK) and using Microsoft.NET.Sdk
.
It may or may not work with other SDKs.
You should have no problems with .vbproj
projects, other than the limitations stated above. Projects in languages other than C# and VB are currently not supported.
Signed assemblies
When stripping annotations from a signed assembly, the signature will be stripped as well.
Work on this is being tracked in issue #2.
Credits
The font used in the package icon is Inconsolata Bold by Raph Levien, Kirill Tkachev (cyreal.org), from Font Library.
The font used in the logo is BloggerSans.otf by Sergiy S. Tkachenko, from Font Library.
Disclaimer: The author of this library is in no way affiliated to JetBrains s.r.o. (the makers of ReSharper) other than being a satisfied cutomer.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Cecil.XmlDocNames (>= 1.1.1)
- Microsoft.SourceLink.GitHub (>= 1.0.0)
- Mono.Cecil (>= 0.11.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Release notes are available at https://github.com/Buildvana/Buildvana.Sdk/blob/master/CHANGELOG.md