Just a bit of feedback of almost a day of playing around converting projects to .netStandard 2.0
This weekend, I played around with .netStandard 2.0, just to see how things would play out. Since I work in the area of Proteomics/Genomics/Scientific computing, I tried converting an open-source project to .netStandard - the project can be found here: https://github.com/basespace/basespace-csharp-sdk. Basically, BaseSpace provides a DataStore similar to DropBox, Box, etc. that can be accessed through a REST API. BaseSpace SDK is a wrapper around the BaseSpace REST API.
Used Visual Studio 2017 - the latest available ‘2’ update on Windows, because the tooling on the Mac seems behind what’s available on Windows.
I downloaded and installed .NET Core 2.0 Preview first, no issues. After restarting my VS command prompt, dotnet --version showed the correct version installed.
With the BaseSpace SDK, this is what I was up against:
<Reference Include="Common.Logging.Core, Version=22.214.171.124, …
<Reference Include="Illumina.TerminalVelocity, Version=126.96.36.199,…
<Reference Include="ServiceStack.Common, Version=188.8.131.52, …
<Reference Include="ServiceStack.Interfaces, Version=184.108.40.206,…
<Reference Include="ServiceStack.Text, Version=220.127.116.11, …
Common.Logging.* and the ServiceStack* dll’s already have an .netstandard 1.0 or greater implementation, so I thought converting those would not be difficult, since .net Core 2.0 has a bigger API surface.
Illumina.TerminalVelocity is a utility project that allows high performance downloads using multiple threads - project can be found here https://github.com/basespace/TerminalVelocity
So I decided to tackle that one first – Forked the project, cloned forked copy, made a new branch. Found the folder where the .csproj was in the cmd window, and executed dotnet new classlib --force – which dutifully created the project as a .net Core 2 project. When running this way, dotnet new should NOT create the default Class1.cs - since we’re only going to have to remember to delete that useless boilerplate class.
One of the things I needed to do to get it to work was to place:
That last line, RuntimeFrameworkVersion seemed to be needed to make things work. By the way, all of this should work from VS2017 – it should be possible to see the .net standard 2.0 as a choice in the drop-down list for .net frameworks – please fix this! [The VS Mac version also does not compile (is it supposed to use the mono5 compiler?) a project that compiles fine on the Windows VS2017. Please Fix!
Next a bunch of dependencies were not accounted for and had lots of undefined types. Either the VS or the R# auto-refactoring points to looking at nuGet, which helped with this. But it would be great to have a directory – if you need type X, you must reference the following nuget package. I found the searching that much more complicated because the names don’t always match the .net 4.x desktop version package names.
Eventually, I found I needed these:
<PackageReference Include=“System.ComponentModel.EventBasedAsync” Version=“4.3.0” />
<PackageReference Include=“System.Runtime.Serialization.Formatters” Version=“4.3.0” />
after which TerminalVelocity compiled as a .net standard 2.0 compatible DLL – yeah!
I then wanted to publish the shiny new thing to our private nuGet server, and found that the .nuspec is the old way, the new way puts the info right into the .csproj file. (I love the new .csproj format that leaves out the .cs files – so much better!)
The first property group looks like this:
<!-- Following tags are for creating nuGet pkg -->
<Description>Fast http range request library</Description>
<Copyright>Illumina 2017 and contributors. All rights reserved.</Copyright>
In Visual studio, there’s a way to right click on the project and create the package, which can then be push’d to nuGet – alternatively msbuild /t:pack /p:Configuration=Release proj.csproj will do the trick. Is there a tool that will import a .nuspec into the .csproj that I somehow have missed, or must one do this by hand?
I then went ahead and continued onto the next project – some observations.
- I like to use the package manager console to add/remove nuget dependencies - works pretty reliably.
- I like to use the “Manage nuGet Packages GUI to find new packages - searching is easier here”
- Sometimes, one needs to unload/reload the project to make things work. I wish this area was Rock Solid. Sometimes it helps to shut-down and reload VS completely, just to make sure there’s no issues.
- With multiple projects in one solution, it helps to unload all the projects, except the one that builds first – convert that one and go.
- Finding the right packages is often hard.
- If you’re using AspNetCore packages in a .netStandard 2.0 dll, you may be out of luck because of a documented bug.
Overall – the experience is a bit frustrating, calling the tooling “rough around the edges” is being modest. It would be good to have stronger tooling support around conversion of both desktop .net projects and net standard 1.x. Even tooling was not built-into Visual Studio but stand-alone would be helpful. The tool could run the portability analyzer and give tell you right away if you can’t port the project easily because it is using an unsupported API.
I’m still not quite done with my conversion – remember if you are on the bleeding edge of .net standard 2.0, you may pay – even some .net Standard 1.x projects may import properly through nuGet. In that case, you need to convert the .net Standard 1.x to 2.0 manually.
– Quick update – 2017-05-23–
A colleague told me to use the latest Preview of VS2017 and not to install Resharper. After that, the experience was much better. I actually got the BaseSpace SDK to work!
Hope the feedback is useful,
brunzefb +AT+ gmail.com