.NET Core versioning
- 9 minutes read - 1706 wordsUnless you have been living underneath a rock you’ve probably noticed that yesterday, during Microsoft’s Connect() virtual event, .NET Core 1.1 was released. In addition ASP.NET Core 1.1 and Entity Framework 1.1 have been released. You can read up on the announcements in the following posts:
- .NET Core 1.1 - https://blogs.msdn.microsoft.com/dotnet/2016/11/16/announcing-net-core-1-1/
- ASP.NET Core 1.1 - https://blogs.msdn.microsoft.com/dotnet/2016/11/16/announcing-net-core-1-1/
- EF Core 1.1 - https://blogs.msdn.microsoft.com/dotnet/2016/11/16/announcing-entity-framework-core-1-1/
At first sight this doesn’t seem like much of a deal. its just a 1.1 version of those frameworks. The reality is a lot more subtle though because ASP.NET Core 1.1 for example consists of several NuGet packages which arent all at version 1.1.0 now. And of course, .NET Core 1.1 really only means the runtime and framework, but not the related tools and SDK which are still in preview. This can cause some confusion as to what is what and how all these version numbers relate to each other. So in this post I want to break it down a bit so you can make some sense of all these version numbers floating around.
Current and LTS releases
The first thing to note is that all the releases I noted above are the first so called “Current” releases, whereas the 1.0 versions (or more accurately the 1.0.1 versions) are what is now called the LTS (or Long Term Support) release. For .NET developers this might be a new concept that didnt exist before. In fact, the only thing we really needed to worry about in the past is the .NET Framework version. So what does “Current” and LTS even mean? Basically, the “Current” version will contain the newest features and changes. They will be released more often than the LTS version, but they havent been fully battle tested like the LTS version. In addition to that, “Current” versions are only supported for three months after the next “Current” version becomes available. What that means is that if I write an application today using .NET Core 1.1 (which is a “Current” release) and .NET Core 1.2 is released (assuming that it will be a “Current” release as well), I need to upgrade my application to 1.2 within the next 3 months in order to get support from Microsoft if something is not working. So basically, in exchange for getting all the latest and greatest features, I need to make a commitment to keep updating my app to the next “Current” version as soon as possible if I want to stay in a supported state. In contrast, the LTS versions dont get all the newest features right away, but lag behind a bit from the “Current” versions. But that also means that I don’t have to update my application every time a new version comes out, because the LTS version I’m using right now (1.0) will be supported by Microsoft for quite a long time, even after a new LTS version is released. Microsoft expects that about 20% of developers will be using the “Current” versions, while the remaining 80% will use the LTS version. It will be interesting to see if that will indeed be the case. I guess it depends on how quickly developer teams are willing and are able to upgrade their applications to the next “Current” version.
NuGet Packages
As I mentioned at the start of this post, ASP.NET Core as well as Entity Framework Core exist of quite a few NuGet packages. With the release of ASP.NET Core 1.1.0, there are now 36 NuGet packages that make up that platform. Some of those are new packages, that havent been released with 1.0.0. For example, there is now a Microsoft.AspNetCore.AzureAppServicesIntegration package. If we have a look at the NuGet page for that package (linked above) well see that this package only has a 1.0.0 version, even though it is part of the 1.1.0 release of ASP.NET Core. Interestingly the GitHub project page for that package reveals that it is tagged with 1.1.0 because it is part of the 1.1.0 release of ASP.NET Core, but as we’ve just seen this doesn’t match with the version of the package. This shows that packages are being versioned independently from each other. Let’s look at another example, the Microsoft.AspNetCore.WebListener package. If we look at the GitHub project page for this package, we see only a 1.1.0 release tag because it is part of the 1.1.0 release of the ASP.NET Core platform. However, looking at the NuGet page reveals that this package is available as both a 1.0.0 and a 1.1.0 version. In this case Microsoft decided that the functionality provided by this package is stable enough to be used with both the “Current” and LTS version of ASP.NET Core. Some of this might seem confusing, especially for those that haven’t been using NuGet for their own shared libraries. But I think that having NuGet packages version on their own independently from each other makes sense. Each of the packages follows semantic versioning rules, so as a consumer of those packages I can reason about the impact that updating a particular package will have on my application. Of course, a lot of the packages that make up ASP.NET Core are tightly related to each other, so in the majority of cases most of them will get a version bump when a new version of the platform is released. That said, ASP.NET Core 1.0.1 only had impact on 5 of the packages.
Tooling
Now the tooling for .NET Core (including the CLI and the Visual Studio tools) is a bit of a different story and something where things get a little bit confusing. Remember that back when .NET Core 1.0.0 shipped, it only shipped with a preview version of the tooling. That is still the case today, even with .NET Core 1.1.0 being shipped. In fact, there are now 3 preview versions and some minor updates to those preview versions, which makes it a bit tricky. So, let’s try to break it down:
.NET Core 1.0.0 RC2 – SDK Preview 1
This was the first preview version of the tooling for .NET Core and it included the dotnet command line tool. It shipped together with the second release candidate for .NET Core 1.0.0. It essentially replaced the dnu, dnvm and dnx tools that we had been using for RC1.
.NET Core 1.0.0 – SDK Preview 2
Preview 2 of the tools is what shipped together with the final .NET Core 1.0.0 version back in June. It still had the dotnet command line tool, but somewhere between Preview 1 and 2 Microsoft decided to drop the project.json format and instead move .NET Core over to the existing MSBuild format although they promised to keep most of the features that made the project.json format so great. But since that work wasn’t quite finished at the time of .NET Core 1.0.0 release they labelled the tools as preview, while the runtime and framework where final versions. Then on the 1st of September a small update to the tools was released with the name .NET Core 1.0.0 SDK – Preview 2-003131. These build numbers are certainly confusing. Interestingly the release was tagged with 1.0.0-preview2.0.1 on the GitHub page which makes a bit more sense to me than the build number.
.NET Core 1.0.0 - SDK Preview 2.1
On the 19th of October .NET Core 1.0.0 SDK - Preview 2-003155 was released. This coincided with the release of .NET Core 1.1.0 - Preview 1 and it was in fact tagged as 1.0.0-preview2.1 on GitHub. It didn’t contain much visible changes to the tools, but it included a preview of the 1.1 runtime. This might easily trip you up because if you’re installing the .NET Core 1.0.0 - SDK Preview 2.1 you are getting Preview2 of the tools, but you are also getting the preview 1.1.0 runtime. This might be the reason that for the final .NET Core 1.1.0 release there is a corresponding .NET Core 1.0.0 SDK - Preview 2-1-003177 release of the tools. In this case they dropped the .1 and replaced it with -1 to make the difference more clear. I still think things could be improved here though. Hopefully this will all make more sense when the tools are finally declared stable.
.NET Core 1.0.0 - SDK Preview 3
There is one final thing to note about the versioning of the tools which is this Preview 3 version. This is really an entirely different beast altogether. Preview 3 is the version where all the work is being done to move .NET Core away from the project.json format and into the csproj and MSBuild world. This is all very experimental right now but hopefully this will be the last preview release of the tooling so we can finally have a stable version. Note also that if you rely on project.json based projects you should avoid installing Preview 3 bits since they don’t support that anymore. You can read all about the way this is going in the announcement post.
.NET Standard
Finally there is one more thing I think is worth mentioning, which is the versioning of the .NET Standard. I can probably spend an entire post talking about .NET Standard and how that all works (which I will probably do sooner or later because I think it’s important for any .NET dev). I do think its worth mentioning though that when you create a .NET Core 1.1.0 application it will import .NET Standard 1.6.1, whereas .NET Core 1.0.0 applications import .NET Standard 1.6.0. Strictly speaking this is a new version of .NET Standard, but it isn’t explictly documented as an existing version of .NET Standard. The sole reason it exists is that it can be used by the Microsoft.NETCore.App 1.1.0 package as a dependency.
Conclusion
As we’ve seen there are quite a few moving parts to consider when using .NET Core and each of them can version independently. This is a feature as far as I’m concerned because it allows for quicker innovation by continously updating small parts of the entire thing. That said, it can become a bit confusing, especially in regard to the tooling which cause a lot of confusion. Hopefully this will all be cleared up soon when Visual Studio 2017 ships so we can move forward.