02 Apr 2013

Strong Naming: One Year Later

No Comments Uncategorized

It is almost 1 year to the date of when I first posted JSON.NET Strong Naming And NuGet Woes and the NuGet compatibility issues have stabilized  This stabilization hasn’t happened through a change from Microsoft, but a change in how publishers of NuGet packages version their libraries.

I am writing this post, because even after one year I am getting very passionate comments on one side of the issue or not, people don’t seem to take a middle road on the strong naming issue. If you don’t believe me take a look at the comments.

Lucky for us, most developers who choose to strongly name their assemblies now are using a versioning mechanism that reduces the chances of breaking referencing assemblies in NuGet.  This “new” versioning technique is actually a non-technique.  Let me explain, instead of changing the version of the assembly with each release, you leave the version of the assembly set, until it is necessary to communicate a major release.

Lets look at JSON.NET again as our standard bearer.  Mostly do to the fact that it is the most widely used strongly named assembly in NuGet.  Since I last wrote my post almost a year ago, 11 releases have been made, however none of those releases caused breaking changes for any of the NuGet packages that referenced a 4.5.x version when built.  You may ask, “So what changed?”  As I alluded to previously the answer is “Nothing.”  NuGet still functions as it did a year ago.  Strong naming still functions as it did a year ago.  .NET assemblies still function the same as they did a year ago.  The strongly named version of Newtonsoft.Json.dll did change either across those 11 releases, it has remained constant at 4.5.0.0.  And that last thing is exactly what was needed to settle down all the referencing problems in NuGet.

Screen Shot 2013-04-02 at 8.46.28 AM

As I talked about in my previous post the main difference between strongly named assemblies and plain assemblies is that when you strongly name an assembly the versions have to match for any referencing assembly, for plain assemblies there is no requirement.  If you put out a new release of a strongly named assembly and don’t change the version, the assemblies that reference it don’t know the difference and are happy to keep using it.

At the time when I posted my previous post, I hadn’t realized that James Newton-King had changed the policy to what I had described above, which is commonly referred to as SemVer.  He pointed this out to me in the comments.

FYI I discussed strong naming a couple of weeks ago –http://james.newtonking.com/archive/2012/03/20/json-net-4-5-release-1-iso-dates-async-metro-build.aspx

No one seems to have read it.

He was right I didn’t read it and that was a failure on my part.  The only reason I bring this up and mention him in this post, is because while I don’t owe him an apology for speaking my opinion, I do have to apologize for using his project as an example of a wider spread problem in the industry at that time.  Projects like JSON.NET are often surrogate children to their owners, and to call out another person’s child in such a public way isn’t fair, so I apologize for that.

My stance on Strong Naming assemblies has softened a little over the past year, mostly due to the fact that it isn’t causing me as much greif as it use to.  I still think it is a plague on .NET developers, unwittingly forced down on high from a VP who read a white paper from 2001.  However, I typically take the stance of, if it doesn’t effect or slow down me, I am going to stay hands off on what other people do.  And right now that is the case.

03 Apr 2012

JSON.NET Strong Naming And NuGet Woes

17 Comments Uncategorized

This post requires a little understanding about how strong naming works. It’s complicated, but basically here is the jist:

When you compile a library against a strong named assembly, only that specific version of the assembly can be used with the assembly that you are compiling with out resorting to heroics. You may say what is the big deal that is how all libraries are compiled and linked. But that isn’t true in .NET, if you don’t have a strongly named assembly, you have for better terms a weakly named assembly.  And with weakly named assemblies there is no enforcement of the version, just the library name.  So this makes it possible for developers to update a referenced library without actually recompiling the original library that referenced it.  This is very powerful in the right hands, and pretty much what makes services like NuGet function with so many intermingling of references between projects.

So once you understand that and it has sort of sunk in.  Now consider what kind of monkey wrench would be thrown in to the NuGet references process if libraries were strongly signed.  Now consider the project that is strongly named is also the 5th most popular project on NuGet with over 125,000 downloads and is one of if not the most interreferenced library in NuGet.  That is a monkey wrench of epic proportions that can cause some real damage isn’t it.

Well you have probably guessed that this isn’t some hypothetical problem by the name of my post. This is an actual problem in NuGet and is causing the community great pains against the ever popular and wonderful library called JSON.NET by James Newton-King. You all have probably heard of it and used it in the past, here is a brief description of it if you haven’t:

Json.NET is a popular high-performance JSON framework for .NET

Features

  • Flexible JSON serializer for converting between .NET objects and JSON
  • LINQ to JSON for manually reading and writing JSON
  • High performance, faster than .NET’s built-in JSON serializers
  • Write indented, easy to read JSON
  • Convert JSON to and from XML
  • Supports .NET 2, .NET 3.5, .NET 4, Silverlight, Windows Phone and Windows 8 Metro.

Now that you understand the scope of the problem and the library involved, consider the fact that the ASP.NET Web Stack is also going to be using this library, so every developer that is going to be using ASP.NET MVC, Web API, or Web Pages is going to be taking on a reference to JSON.NET in the next release of the framework.

I hope you are starting to realize the boondoggle that is being created here.  Because there are some popular libraries that are slow to update because of their development cycles and the maintainers can’t jump on every JSON.NET release every month, and sometimes daily as happened in January 2012.

These monthly releases create undue pressure on the community as a whole especially when this library is one of the most referenced libraries on NuGet. And with the ASP.NET and many other teams in Microsoft moving to NuGet as distribution model, this problem is only going to get worse. And what are the chances that Microsoft is going to want to update the ASP.NET framework monthly and sometimes daily, based on James continuous release cycles.

Don’t get me wrong, I love it when developers are constantly updating their libraries, but because of the scope of JSON.NET’s use, it is creating a burden on the ecosystem as a whole. I am not advocating that James stop updating JSON.NET monthly and daily if he sees fit, what I am advocating is dropping the strong naming of libraries pushed to NuGet. That is why I am writing this blog post and that is why I am hoping you will support me and my effort to get James to stop signing NuGet assemblies.

Please support me and the community as a whole by voting up this request for JSON.NET to stop being signed on NuGet assemblies.

Work Item 22458 : Don’t Strong Name NuGet Assemblies

All that you have to do if you support this effort is to click the vote button on the work item. And leave a comment of support if you have anything to add to what I have said.

Thanks for the help and support.

13 Dec 2011

Cleaning Up Your Git Repository For NuGet 1.6

10 Comments Uncategorized

NuGet 1.6 was released today. And with it came some great new features, one that I am particularly excited about is.

Using NuGet Without Checking In Packages (Package Restore)

NuGet 1.6 now has first class support for the workflow in which NuGet packages are not added to source control, but instead are restored at build time if missing. For more details, read the Using NuGet without committing packages to source control topic.

The reason for this is that it finally allows us to remove the packages directory and all the packages from our repository.  Which I always thought created a mess of source control systems, and required unnecessary check-ins. It also created a huge amount of bloat especially since some projects (cough… NUnit) included so much extra crap that nobody needed and required all that extra storage space in the repository and commit history.

Setup

Let’s assume that you have a solution that is either already using NuGet, or planning to use it, and that you want to set up the no-commit workflow.

Right click on the Solution node in Solution Explorer and select Enable NuGet Package Restore.

Enable NuGet Package Restore Context Menu item

That’s it! You’re all set.

(taken from http://docs.nuget.org/docs/Workflows/Using-NuGet-without-committing-packages)

.gitignore

Next we will want to add the following to your .gitignore file. (create one if you don’t already have one) And add the following to the top of it.

# Don't include NuGet Packages
packages/

This will make sure any changes in the packages directory will be ignored when adding to the repository.

Make sure to commit these changes before the next step.

$ git add .
$ git commit -am "updating project for NuGet 1.6"
$ git push origin master

Cleaning up your repository

This next step is optional, but the purpose of it is to reduce the size of your repository. And for the more OCD among us, remove all reference to the packages directory so it is like it never existed.

$ git filter-branch --index-filter 'git rm --cached --ignore-unmatch -r ./packages/*'
Rewrite 48dc599c80e20527ed902928085e7861e6b3cbe6 (266/266)
Ref 'refs/heads/master' was rewritten

$ git push origin master --force
Counting objects: 1074, done.
Delta compression using 2 threads.
Compressing objects: 100% (677/677), done.
Writing objects: 100% (1058/1058), 148.85 KiB, done.
Total 1058 (delta 590), reused 602 (delta 378)
To git @ github.com:nberardi/some-project.git
 + 48dc599...051452f master -> master (forced update)

Cleanup and reclaiming space

While git filter-branch rewrites the history for you, the objects will remain in your local repo until they’ve been dereferenced and garbage collected. If you are working in your main repo you might want to force these objects to be purged.

$ rm -rf .git/refs/original/

$ git reflog expire --expire=now --all

$ git gc --prune=now
Counting objects: 2437, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (1378/1378), done.
Writing objects: 100% (2437/2437), done.
Total 2437 (delta 1461), reused 1802 (delta 1048)

$ git gc --aggressive --prune=now
Counting objects: 2437, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2426/2426), done.
Writing objects: 100% (2437/2437), done.
Total 2437 (delta 1483), reused 0 (delta 0)

Note that pushing the branch to a new or empty GitHub repo and then making a fresh clone from GitHub will have the same effect.

(taken from http://help.github.com/remove-sensitive-data/)

Happy Coding