static void

Updating a class library to dotnet Core RC2

Published Wednesday 18 May 2016

net Core RC2 came out on 2 days ago (May 16 2016). I tried upgrading a simple class library so that it can support .net Core RC2 plus older .net frameworks.

It was relatively straightforward, unlike RC1. Here's what I did.

The library I used was very simple (my public holidays project).  There is just one project. We're not doing tests for now- we're using vanilla MsTest. RC2 still only supports XUnit, but we should get MsTest for RTM. For now, we want to be able to use the "classic" solution, with tests, and add a parallel "Core" solution that sits alongside it.

Installing RC2

Project.json

I added a project.json, but I added it alongside the .csproj. There was a bug in RC1 that Visual Studio/ nuget didn't like csproj and project.json together (https://github.com/dotnet/corefx/issues/4544, last updated April, see also Marc Gravell's instructions at http://blog.marcgravell.com/2015/11/the-road-to-dnx-part-1.html, November 2015 so RC1). Let's find out if it's fixed.

{
  "version": "1.0.0-*",

  "dependencies": {
    "NETStandard.Library": "1.5.0-rc2-24027"
  },

  "frameworks": {
    "netstandard1.3": {
      "imports": "dnxcore50"
    }
  }
}

I opened up the old solution. Building in Visual Studio broke: "Your project is not referencing the ".NETFramework,Version=v4.0" framework. Add a reference to ".NETFramework,Version=v4.0" in the "frameworks" section of your project.json, and then re-run NuGet restore."

The workaround (from the github issue) is to add <ResolveNuGetPackages>false</ResolveNuGetPackages> to the .csproj. If you have packages, tough.

First dotnet build

There's documentation on the "dotnet build" command here: http://dotnet.github.io/docs/core-concepts/core-sdk/cli/dotnet-build.html

>dotnet build
Project x does not have a lock file
Project x does not have a lock file

Saying it twice doesn't make it any more helpful. The lock file is something to do with a package restore. 

>dotnet restore
log  : Restoring packages for C:\...\project.json...
info : Committing restore...
log  : Writing lock file to disk. Path: C:\...\project.lock.json
log  : Restore completed in 950ms.
>dotnet build

It builds!

We now have a dll and pdb in bin/Debug/netstandard1.3
We also have a json file, (x.deps.json), which shows you everything in .NETStandard,Version=v1.3

Parallel solutions

I created a second solution alongside the current solution (essentially the same, minus the test project).

Next, alongside the current project, I added an xproj file (a cut-down csproj). To get this file, I created a new Core library in Visual Studio in a different folder, and stole the xproj. I had to change the <RootNamespace>x</RootNamespace>.

I also changed the  <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath> ( to .\bin\core\ ) so building the current and new projects put things in different places. Note this only works in Visual Studio- "dotnet build" doesn't look at the .xproj. Instead you have to >dotnet build -c Release -o .\bin\core\ -f netstandard1.3 (note you have to specify the framework when you use --output).

Multi-targeting

Adding older frameworks to project.json is as simple as adding the targets (which are the same as used in nuget).

  "frameworks": {
    "netstandard1.3": {
      "imports": "dnxcore50"
    },
    "net35": { },
    "net40": { }

   
This works, but in Visual Studio it has a deep output folder structure. Using the dotnet command line, it's exactly what you'd expect.

Not sure why Visual Studio adds more levels.

Packing up

Nuspec is now in project.json. Add json like this:
  "packOptions": {
    "summary": "Wonderful library",
    "tags": [ "Wonderful" ],
    "owners": [ "me ],
    "projectUrl": "
https://github.com/xxx",
    "licenseUrl": "
http://opensource.org/licenses/MIT",
    "repository": {
      "type": "git",
      "url": "
https://github.com/xxx"
    }
  },

We now use "dotnet pack" instead of "nuget pack": http://dotnet.github.io/docs/core-concepts/core-sdk/cli/dotnet-pack.html
 
>dotnet pack -c Release -o .\artifacts

ToDo

Hopefully appveyor will roll out RC2 support soon (maybe this week?), and we can have easy CI builds. Once that is in-place, I will use it to publish the pre-release package to nuget.

More complex dependencies, particularly on older parts of .net like ADO, will be more challenging. It would be easy to find yourself with heavy compiler directives all over your code.

Sometime after RTM, project.json will be phased out, and we move back to csproj (hopefully improved). I suspect this will come with the release of the next version of Visual Studio (2017?).

Previously: NDC Video Link Dump 2 (25 Feb 2016)