This is a short follow up to my NuGet Like A Pro post. I left an additional step out of that post, even though I almost always need to to do it. I didn’t think this next step was widely applicable, and wanted to position the previous post as a “Super Duper Happy Path” that most people could follow with out confusing digressions.
However, I did my self a disservice by leaving it out, because now whenever I need to refresh my memory by reading my own post, I am left still having to figure out this one step again. So, I’m going to post it here so that I’ve got all my documentation in one place.
If you don’t know what they are, then you probably don’t need to read this post. However, if you are curious they are an artifact created when using Code Contracts.
Code Contracts provide a language-agnostic way to express coding assumptions in .NET programs. The contracts take the form of preconditions, postconditions, and object invariants. Contracts act as checked documentation of your external and internal APIs. The contracts are used to improve testing via runtime checking, enable static contract verification, and documentation generation.
In other words, Code Contracts are another form of static analysis and client code needs to know about your contracts in order to properly evaluate their own contracts. This is where the contract assembly comes in, it provides the contract information about the assembly in your package.
So you need to create this assembly, put it in your nuget package so that the contract checker can find it, and then give nuget a hint indicating that only the “normal” assembly should get a project reference, while the contract assembly (which only contains metadata) should not be referenced by the project.
Creating the Contract Assembly
This step is easy, but I will include it for those who are new. First one must visit the Visual Studio Gallery and download the tools. Once the tools are installed, the Visual Studio project properties page will grow a new blade, pictured below.
I check almost everything in the “Static Checking” section and leave “Runtime Checking” alone. It would be off topic to explain why in this post, but you can visit the Code Contracts website and make your own decision. You can also choose not to turn anything on, yet still build the Contract Reference Assembly. This will let clients using Contracts know that you don’t have any.
By default, the Contract Reference Assembly is not configured to build, but as you can see in the red rectangle, I have turned it on.
Now when I build my project, the additional assembly is created (below the build output folder, in a subfolder called “CodeContracts”)
Adding to the package
Now that you have the assembly you can let nuget know about it by adding a file reference to the nuspec file. This reference goes in the files node, which is a child of the package node. I usually put it right after the metadata node:
</metadata> <files> <file src="bin\Debug\CodeContracts\TemporaryFile.Contracts.dll" target="lib\net45" /> </files> </package>
After rebuilding, you will see that the Contract assembly is now packaged with the normal library.
However, if you were to use this package as is, NuGet would add a reference to the Contracts assembly as well as the library. To prevent that, we provide NuGet a white list of assemblies which should be referenced, and it will ignore the rest.
To do this, add a child node to metadata called “references” and a “reference” node for the normal library.
<references> <reference file="TemporaryFile.dll" /> </references> </metadata> ... </package>
Now rebuild again, and the NuGet Package Explorer will indicate that the assembly references have been “filtered”.
So, to distribute Contract Assemblies (or other any assembly which should not be referenced) follow the steps above. First create the assembly you want to distribute. Next add a file reference to the nuspec which points at the new assembly. Then, add a references node and add references to each assembly which should be referenced (the new assembly should not be in this section, but the original assembly should be). After filtering your references you are ready to go. Upload your package to your favorite feed (nuget.org, myget.org, proget, etc…) and pour yourself a drink.