comments edit

Back in December, I blogged about how poor the NuGet package submission process was. You had to clone a HUGE repository that had all the other packages, add your package files to it, and submit a pull request. It was something that we had meant to last a couple weeks, and it lasted a few months, way overstaying its welcome.

The good news is that that process is now obsolete! Instead of have a brand new gallery site that lets authors publish packages very easily.

And the site it.. drums… http://nuget.org!

Who is this site for?

To set expectations, please note that this site is not feature complete yet, and is still rough in many ways. Eventually, it will be a place for both package authors and consumers, but in the short term, it’s primarily useful to package authors.

So basically, this site provides a complete (and much better) replacement for the old package submission process, and at this point that is its main focus.

So if you are using NuGet from Visual Studio to install packages, you can probably ignore this site for now. It will be come interesting later, but it isn’t now. You’re certainly welcome to browse around it, but there is no point in creating an account now unless you have packages to submit.

Getting started with the site

Here is what you need to do if you’re a package author wanting the submit a package.

  • Go to http://nuget.org, click Sign In, and Register Now
  • After registering, you’ll get an email with a link you need to click (check your junk mail, it’s probably there!).
  • An admin then needs to approve your account (see below for the reason behind that)
  • Once you’re approved, you can just go to the Contribute tab and click Add New Package to upload your .nupkg files. They will be live on the feed instantly, though it may take a couple minutes for it to show up on the site itself.

If you submitted packages with the old process

If you previously submitted packages using the old process, you will need to be given ownership of those packages in the new gallery before you can upload new versions.

Just ping @davidebbo on twitter and I can take care of that.

Why the approval process?

Eventually, there won’t be any approval process. The reason we chose to have one initially is that the site is still very young and we want to take it step by step. We will generally approve anyone that wants to get packages up there.

If you registered and don’t see your account getting approved, please just ping me or Phil Haack on twitter (@davidebbo, @haacked).

What, no Live ID or OpenID?

I know, this is really something we should be supporting, and we will later. We had to make that cut in order to get the gallery out sooner, as the current situation with package submission was simply not sustainable.

Built on Orchard

The NuGet gallery was built using Orchard, which itself is still very young (1.0 release is around the corner). This could be one of the first real sites built using it, so it is both a great learning experience for the Orchard team, and a good showcase of the technology.

There were certainly a number of Orchard issues during development, but since the team is just down the hall from us, they took good care of things!

Open Source

Just like NuGet itself, the gallery site was built as open source. Most of the development was done by NimblePros.

If you want to look through the sources, there are two CodePlex projects, one for the Orchard gallery site and one for the backend.

The gallery is at http://orchardgallery.codeplex.com, and the backend is at http://galleryserver.codeplex.com/.

How to report issues and give feedback

If you run into issues or want to give feedback about the site, feel free to start a discussion or file a bug on http://orchardgallery.codeplex.com.

comments edit

This is part 3 of the series on NuGet versioning.

In part 1 & 2, we described the DLL hell problem, as well as the algorithm NuGet uses to achieve the best possible results.

Let’s now look at how we can achieve runtime unification of assemblies using binding redirects.

Strong names and binding redirects

Another important part of the story that we haven’t yet discussed is assembly strong naming. When an assembly has a strong name, the binding to that assembly becomes very strict. That is, if assembly C depends on assembly X 2.0, it’s not going to be happy with any other version of X, even if it’s X 2.0.0.1.

Note: I’m now talking about assembly versions rather than package versions, but let’s assume that they match, as will usually be the case.

Going back to our earlier sample in Part 2, what this means is that the package-level unification that we performed would have ended up breaking the app!

Recall that we had:

  • A depends on X 1.1 (as in ‘>= 1.1’)
  • B depends on X 1.2
  • C depends on X 2.0

And then (with the NuGet 1.1. twist), we ended up installing X 2.0.1.5, which doesn’t match what A, B or C are looking for! If you then try to use A at runtime, and it itself tries to use X, you’ll get a nasty error that looks like:

Could not load file or assembly ‘X, Version=1.1.0.0, Culture=neutral, PublicKeyToken=032d34d3e998f237’ or one of its dependencies. The located assembly’s manifest definition does not match the assembly reference.

While this looks scary, it’s really just saying things the way they are: A was looking for X 1.1 and X 1.1 was nowhere to be found (since we have X 2.0.1.5).

The answer to this problem is to use binding redirects, which provide a simple and effective way of telling the runtime to bind to a different version than what an assembly was built against. e.g. in this case, you would add this to your web.config (or app.config):

<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="X"
publicKeyToken="032d34d3e998f237" culture="neutral" />
<bindingRedirect
oldVersion="0.0.0.0-2.0.1.5" newVersion="2.0.1.5" />
</dependentAssembly>
</assemblyBinding>
</runtime>


This is basically telling the the runtime: “hey, if anyone asks you to load any version of X that’s less than 2.0.1.5, please go ahead and load 2.0.1.5 instead”.

Once you do that, our A, B and C friends will all happily work against X 2.0.1.5. We have now achieved assembly-level unification to go along with our earlier package-level unification.

Need some help writing those binding redirects?

You may be thinking that writing those binding redirects by hand is not as simple as I make it sound, and that it would be nice if you didn’t have to worry about the details.

If so, you’re in luck because NuGet comes with an Add-BindingRedirect command which will generate all the binding redirects for you!

It doesn’t take any parameters. All you have to do is run it, and then check out your config file to see what was added (if you’re curious). It’s pretty smart about only adding things that are needed, so in simple situations that don’t call for it, it will not make any changes.

Note: make sure that you build your app before running this command. We’ll try to not make this required in the future, but for now, please remember to build first or it won’t work correctly.

We are also considering ways to automate things even more such that you don’t need to run any commands at all, and the binding redirects would get managed for you as you add packages. Not sure when we’ll get there, but it should be feasible. in the meantime, just running Add-BindingRedirects is still a big help over hand writing those sections.

Alternative to binding redirects

OpenWrap uses a different approach to solve that same issue: it modifies all the assemblies at install time to strip the strong name from them, hence allowing them to work with each other regardless of versions. Though it is a viable technique, we chose not to do this for a number of reasons.

The first is that it doesn’t feel right to take an assembly that has been strongly named and signed by its author and turn it into something with no trace of the original signature. It may also have implications in some environments that only allow signed assemblies to run.

The second reason is that it violates one of our key design goals for NuGet, which is to make it easy to do things that you could otherwise have done yourself without NuGet. i.e. once NuGet has done its thing, it stays out of the way of your app, and you very much have a ‘normal’ app, not much distinguishable from what you would have if you had put it together without NuGet. But with the rewriting approach, you would end up with something that is quite different, making the installation process feel a little too ‘magical’ and not transparent enough.

The third reason may be the most important one: the rewriting approach locks you into using OW for everything. e.g. suppose that assembly A uses assembly X, and that you get both via OW. And now suppose that you get some other assembly B through some other mean (because there is no package for it yet), and that assembly also references X. You drop B.dll in bin and expect it to just work. But if X had been stripped of its strong named, B.dll would be broken (as it would fail to load the strong named X.dll). On the other hand, with the binding redirect approach, everything just works naturally, since no assemblies have been modified.

In the end, it comes down to NuGet and OW having rather different design goals, even though at a high level they share some similarities.

Update: it turns out that OW does not yet do this but it is planned for the next version. See Sebastien Lambla’s new post on the topic for details.

Conclusion

This completes this 3 part series on NuGet versioning, While there are still many areas that NuGet has not yet tackled, it has solid core approach to versioning and dependency management that it can build on.

comments edit

This is part 2 of the series on NuGet versioning.

In part 1, we described the two sides of DLL hell, as well as how assembly Unification is superior to Side by Side.

Let’s now dive into the algorithm that NuGet uses to deal with versioning.

Package vs. Assembly

It should be noted that at the top level, NuGet deals with Packages rather than assemblies. Those packages in turn can bring in zero or more assemblies. The assembly versions may or may not match the package version, though in most cases they do.

The following discussion on versioning is referring primarily to Package versions, though the reasoning applies equally well to DLL versions (and essentially falls out of it).

How NuGet specifies dependency versions

The NuGet syntax for specifying package dependency versions borrows from the Maven specification, which itself borrows from mathematical intervals. e.g. when component A depends on component X, it can specify the version of X that it needs in two different ways (in the .nuspec file):

  • A range, which can look like [1.0,3.0), meaning 1.0 or greater, but strictly less than 3.0 (so up to 2.*). See spec above from more examples.
  • A simple version string, like “1.0”: this means “1.0 or greater”

Your first reaction may be that #2 is counter intuitive, and should instead mean “exactly 1.0”. The reason it means “greater or equal’” is that as things turn out, this is what should be used most of the time in order to get the best behavior, i.e. in order to avoid both of the extremes of DLL hell mentioned above. This reason will soon become clear.

The version selection algorithm

Having a version range is only half of the puzzle. The other half is to be able to pick the best version among all the candidates that are available.

Let’s look at a simple example to illustrate this:

  • A depends on X 1.1 (meaning ‘>= 1.1’ as discussed above)
  • B depends on X 1.2
  • C depends on X 2.0
  • X has versions 1.0, 1.1, 1.2, 2.0, 3.0 and 4.0 available

The version resolution used by NuGet is to always pick the lowest version of a dependency that fits in the range. So let’s see what will happen in various scenarios:

  • If you just install A, you’ll get X 1.1
  • If you just install B, you’ll get X 1.2
  • If you just install C, you’ll get X 2.0
  • If you first install A, then B then C

  • You’ll initially get X 1.1 when you install A

  • X will be updated to 1.2 when you install B

  • X will be updated to 2.0 when you install C

The crucial point here is that even though A and B state that they can use any version of X, they are not getting forced into using anything higher than necessary.

It may very well be that A does not work with much higher versions of X like 3.0 and 4.0, and in that sense you can say that the specified range is ‘wrong’. But that is simply not relevant unless you are in a situation where you must use those higher versions due to a different component in the same app depending on those higher versions.

If we had instead specified exact versions, we would not have allowed anything to work together, even though the components may very well be backward compatible up to a point. That is one of the extremes of DLL hell discussed in Part 1: inability to find a version that everyone can work with.

Likewise, if the algorithm had picked the highest version in range, we would have ended up with X 4.0 in all scenarios. That is the other extreme of DLL hell: a newly released component breaks scenarios that were working before.

The simple algorithm NuGet uses does a great job of walking the fine line between those two extremes, always doing the safest thing that it can while not artificially disallowing scenarios. As an aside, that is essentially the same as what Maven does (in the Java world), and this has worked well for them.

When an upper bound makes sense

In most cases, simply specifying a minimum version is the way to go, as illustrated above. This does not imply that upper bounds shouldn’t be specified in some cases.

In fact, an upper bound should be specified whenever a component is known not to work past a certain version of a dependency.

e.g. in our example, suppose that A is known not to work with X 2.0 or greater. It would then be fine to specify the range as [1.1,2.0). And in the scenario above, when you try to install C after installing A, you’d get a failure to install. i.e. A and C simply cannot be used in the same app. Clearly, this is a bit better than allowing the install to happen and then having things break at runtime.

But the key thing here is that the incompatibility has to be known before such range is used. e.g. if at the time A is written, X 2.0 doesn’t even exist, it would be wrong to set a range of [1.1,2.0).

I know, it may feel like the right defensive thing to do not to allow running against something that doesn’t yet exists, but doing so creates many more issues than it solves in the long run.

The rule of thumb here is that a dependency version is “innocent until proven guilty”, and not the other way around.

Backward compatibility is in the eye of the consumer

A subtle yet very important point is that simply knowing that version 2.0 of X has some breaking changes over version 1.2 doesn’t mean all that much.

e.g. you may be tempted to say that if B uses X 1.2 and X 2.0 has some breaking changes over 1.2, then B should never use 2.0. But in reality, doing so is too conservative, and causes the second form of DLL hell (inability use some components together, and general lack of flexibility).

The more important question to ask is whether X 2.0 has breaking changes that affect B. B may very well be using a small subset of the API’s and be unaffected by the breaking change. So in this situation, you should not jump to the conclusion that you need a [1.2,2.0) range.

Again, “innocent until proven guilty”. Or maybe I should say “give (DLL) peace a chance”, or “if it ain’t broke, don’t prevent it”. Or maybe I should stop there ;)

Credits to Louis DeJardin on convincing me of this key point.

A few words on Semantic Versioning

Semantic Versioning (SemVer) describes a way for authors to define versions in a way that they have a consistent semantic. In a nutshell, semantic versions look like X.Y.Z (Major.Minor.Patch), such that:

  • A change in X is a breaking change
  • A change in Y adds functionality but is non-breaking
  • A change in Z represents a bug fix

The use of this versioning scheme is not widely adopted today, but I think it would be beneficial if component authors (and NuGet package authors) followed it more.

Technically, if all components actually honored SemVer, we could always safely move from 1.0 to 1.1, as it would be guaranteed to be a non-breaking upgrade. But in practice, this would not work well today given how a change in Minor version (Y) does often contain breaking changes.

It is also worth noting that the NuGet algorithm described above makes this mostly unnecessary, because there is no reason to use 1.1 if the component asks for 1.0. Unless of course some other component needs 1.1, in which case we would use it.

In part 3, we will discuss how NuGet makes use of CLR binding redirects to achieve assembly unification.

comments edit

NuGet makes it easier than ever to get all kind of libraries into your .NET apps. While that is its most obvious benefit, NuGet also helps tremendously with managing dependencies and versioning, which can normally be a complicated process.

In this multipart series, I will cover the following topics:

Before going too deep into the NuGet behavior, let’s step back and look at the problem we’re tackling: the infamous DLL hell.

The two extremes of DLL hell

I have seen the term ‘DLL hell’ used to describe situations happening at both ends of the spectrum.

The more common usage refers to what occurs when the versioning policy is too loose (or non-existent). This is the classic old 16-bit Windows issue where a DLL gets updated system wide, and everything on the system that was using the old version is now using the newer one, sometimes causing breaks due to incompatibilities.

At the other end of the spectrum, there is what happens when the versioning policy to too tight, as is often the case with the GAC. Here, you can lose the ability to use components A and B at the same time, because they each want to use a different version of component X, and the system won’t let those be unified.

So in one case we get in trouble because apps get broken, while in the other we get in trouble because apps can’t use the components that they need.

BIN deployment limits the scope of the issue

To begin with, it’s worth emphasizing that NuGet never installs assemblies machine wide. In particular, it will never put anything into your GAC. Instead, all assemblies are bin deployed, which means they only affects the current app. This reduces the scope of the issue because it moves the concern from a potential machine wide DLL hell to a potential application wide DLL hell. So even if things are not done correctly, you can still get bad things to happen within an app, but you’ll never mess up a different app.

So NuGet’s focus is on doing the right thing within this one app.

Unification versus Side by Side: a clear choice

When dealing with situations where two different versions of a DLL appear to be needed, there are two possible approaches.

The first approach is unification, which consists in picking one version of that DLL and using it for the entire app. This can require the use of Binding Redirects, as we will discuss later in the series.

The second approach is to allow both versions of the DLL to run Side by Side. e.g. A could be using X v1.0 while at the same time B could be using X v1.1.

NuGet always uses unification, as Side by Side is evil for several reasons. First, using Side by Side is difficult for a practical reason: the bin folder can only contain one file named X.dll. But even if you get around this (e.g. by going crazy with AssemblyResolve events), it is likely to get you in trouble because many assemblies don’t expect this. e.g. an error logging component expects to be the only one there, and would end up fighting with its evil twin if they ever came to run in the same app domain at the same time.

So let’s settle this one: two versions of an assembly should never be loaded in the same app. I’m not saying that there aren’t any situations where it may legitimately arise, but for the most part, it’s best to not go there,

In part 2, we will discuss how NuGet deals with package and assembly versioning.

comments edit

I had been wanting to move my blog for a while, mostly so I could use my own domain name instead of msdn.com. With the new year around the corner, I figured that was a good time to do it!

My feed goes through feedburner, so if you were subscribing to my blog before, it should just continue to work, so for the most part it’s a non-event. For reference, my old blog was at http://blogs.msdn.com/davidebb/.

I also dropped my blog’s name, which was “Angle Bracket Percent”. The reason should be fairly obvious if you’ve been following ASP.NET news: that name was based on the syntax used by aspx/ascx pages (e.g. <%= “Hello” %>). But now, with the Razor syntax being the new hot thing, that name was getting a bit old. And renaming it after the Razor syntax would have meant calling my blog “at”, which just didn’t work as well :)

So I went with the most boring possible name: my own!