Search Posts

PCL netstandard multi-target library implementation using project.json

Remarks

At the time of this writing project.json is being moved in to the .csproj file.

However, this requires Visual Studio 2017 and might not be mature enough.

So if you’re still rollin’ VS 2015 or want to stick with project.json, this tutorial is for you.

The new black

As a Xamarin (Forms) developer we’ve historically heavily on Portable Class Libraries; PCL.

However, the world has changed with the introduction of net core and the new black is netstandard type libraries.

By converting (below) you’ll be hanging with the cool kids while not disrupting your architecture.

And as we’ll see, you’ll be able to support all .net platforms with your new project; everything from .net 4.x to netstandard.

Requirements

Convert PCL project to netstandard

To gain all the benefits of PCL while staying in the game, converting your PCL libraries to netstandard is a good first step.

Once done your libraries will no longer rely on specific paths to referenced packages and will be ready for multi-target.

Step 1 – backup packages.config

We’ll need to strip our lib of current package references, so backup your packages.config first.

packages backup
Backup packages.config in your favorite editor

 

Step 2 – remove packages.config

To make the conversion work we need to kill packages.config – its content will migrate to project.json.

So either uninstall all packages or delete packages.config and remove the references manually.

Step 3 – Target Net Platform

Check out project properties (Ctrl+Enter) and click that Target Net Platform link on the Library tab. It will be fun, promise.

If this failed you still have NuGet package references or didn’t remove packages.json.

Target Net Platform
Target .Net Platform Standard

 

Once converted change the target to .NETStandard 1.4 for Xamarin support.

Support PCL references

Your library now expects references to also be .NETStandard.

To support PCL references, we need to import the PCL profile in project.json.

Open it for editing and modify the frameworks section:

Read more

Step 4 – reinstall packages

You can now reinstall your packages. One way is to directly edit the project.json and see how “Restoring packages” is executed as you type.

But if this is your first mission, just installing them with manager / console is recommended.

I prefer the Package Installer extension for Visual Studio.

Alright – we not got ourselves a basic netstandard library! But in the time of writing that won’t really roll well with Xamarin, so multi-target is our next step.

Multi-target using project.json

As seen above the project.json has a target framework. We will now complement that list causing the dotnet cli to produce separate outputs for each framework.

This tutorial is based on HLI.Data which is open source, so you can check out the source code at GitHub.

We’ll add content step-by-step in the below sections.

Frameworks

What you need to add a framework is the correct “moniker” and add those to the frameworks section:

Dotnet build in Visual Studio 2015

While your project will build the default framework in VS 2015 it will not parse the whole project.json and you might get fooled (gotcha!) to think the build is working when it’s not.

But you can easily work around this by adding dotnet build  as an post-build event using Project properties > Build Events:

When  dotnet build compiles successfully the output will contain one folder for each platform:

Bin output of multi target
Bin output of multi target

Dependencies

This is the big one, the not-a-moon part. Remember how we don’t have any reference paths any more?

Shared dependencies – NuGet packages

So how to get that to jam with multiple frameworks? Our re-added NuGet references should already be included in the shared dependencies section.

You should find this in the top or bottom of your project.json (containing your NuGet references, not mine):

So these will be used by all your target frameworks; when dotnet ci compiles for .Net 4.5 for example, it will try to find a .Net target for each of the above.

Framework Assembly Dependencies

Now this is where it gets interesting. For each target framework you can add a section for “dependencies” (full .Net) and / or “frameworkAssemblies” (PCL).

This is my experience with each framework:

  • net4x – you usually don’t have to add anything to “frameworkAssemblies”
  • .NETPortable (PCL) – will need each framework assembly without version:

  • netstandard – with netcore we only use what we need so every part of ,net is an (open source!) NuGet package. So find the NuGet for each assembly library. Example:

But don’t copy paste the above and add unneeded dependencies.

Build and for each error add the required library to each framework in your project.json.

Conclusion

Alright – you’re done! Enjoy your library responsibly and please come back for your own NuGet packaging using project.json!

Gotchas for multi-target with project.json

What – it didn’t work for you? Well check out these foobars and if still stuck Google – the programmer’s Nr 1 skill.

Supports attribute

You shouldn’t need this and it will more likely cause errors since all referenced libraries will now be expected to conform to for example x86.

I got stuck a while trying to use this and in the end it was just a cause for build failures in dotnet cli.

Testrunner attribute

Well this one ain’t so bad – in a test project where you target a limited number of frameworks. In your lib it might and will cause errors.

%d bloggers like this: