.NET Standard Library with Xamarin Forms

Its time to welcome the new kid to the block with .NET Standard Libraries. Currently with PCL’s we are dealing with Profile Based PCL’s and you may have heard of Profile 259 which is the common profile most of us use with Xamarin Forms. .NET Standard Libraries are the successor.

Update: For Visual Studio 2017, please see Visual Studio 2017, .NET Standard and Xamarin.
The below is left for reference, for Visual Studio 2015.

Why Update

.NET Standard Library is the new way to define portable class libraries and is a replacement for profile based PCL’s. If you are wondering why you would want to update now the reason is because package authors are already starting to update. I recently tried to download AutoMapper 5.0 due to its massive performance gains, however I got stopped in my tracks when it required .NET Standard Library.

.NET Standard Libraries can reference Profile Based PCL’s but a Profile Based PCL can’t reference a .NET Standard Library. (I found out it can, but people are experiencing a lot of issues in doing so). Where as a .NET Standard Library referencing a PCL or other .NET Standard Libraries I have had no issue with.

Updating Your Projects

Warning: Try this out on a separate project first not on a production project, this can be an unpleasant experience. This is also using Visual Studio 2015 Update 3.

Download .NET Core

Make sure you have the latest .NET core, specifically .NET Core 1.0 for Visual Studio. If you don’t you run into all kinds of strange errors (as I did).

Change your Target

Go to the properties of your Profile Based PCL and click on Target .NET Platform Standard.

Targeting

Note: You are most likely going to see this error.

Nuget

Press OK. Uninstall all Nuget packages and then try to change your target again. Choose .NET Standard 1.1 or 1.3. You can look at the .NET Platform Support to see which platforms each netstandard supports.

netstandard

Target Framework Monikers (TFM)

Because the shift to .NET Standard Libaries will means that Profile Based PCL’s and .NET Standard Libraries will have to live in harmony. To accommodate this you can declare an Imports section in your framework to allow Profile Based PCL’s to be referenced from your .NET Standard Library.

Go to the project.json file and insert the imports section as demonstrated below.

{
  "supports": {},
  "dependencies": {
    "Microsoft.NETCore.Portable.Compatibility": "1.0.1",
    "NETStandard.Library": "1.6.0"
  },
  "frameworks": {
    "netstandard1.1": {
      "imports": [
        "portable-net45+win8+wpa81+wp8"
      ]
    }
  }
}

Download Nuget Packages

Re-download the Xamarin Forms Nuget package, it should now install. if you didn’t add the imports above it will complain that the package does not support .NET Standard. You can also test out downloading AutoMapper 5.0 as it is a .NET Standard Package to see .NET Standard and Profile Based PCL working side by side. Once it is all downloaded you will have a project.json similar to below and you will need to reference your PCL from your native project again as the re-targeting generally removes it.

{
  "supports": {},
  "dependencies": {
    "AutoMapper": "5.0.0",
    "NETStandard.Library": "1.6.0",
    "Xamarin.Forms": "2.3.1.110-pre1"
  },
  "frameworks": {
    "netstandard1.1": {
      "imports":
        "portable-net45+win8+wpa81+wp8"
    }
  }
}

And your references will now look similar to this.

references

Project.json Everywhere

I thought project.json was dead? Well it is, sort of. What is happening is the project.json is having parts moved back into the .csproj as they move back to msbuild. However project.json will still remain to handle nuget dependencies or it may get called nuget.json or something similar in the future. You can listen to this announcement at ASP.NET Community Standup – May 10th, 2016 (I set this link to start at 28:30 where Damian starts talking about the change)

As of Preview 2, project.json still exists so we need to change our packages.config into a project.json in each of the native projects. Delete the packages.config and replace with a project.json. You need to manually create these. I have the Android one as an example below. Take a look at XamarinForms.NetStandard sample app for the others definitions.

{
  "dependencies": {
  },
  "frameworks": {
    "MonoAndroid,Version=v6.0": {}
  },
  "runtimes": {
    "win": {}
  }
}

Note: If you get the below in any of your project.json files

Microsoft.NETCore.Portable.Compatibility": "1.0.1

This causes issues in Xamarin.Android and you might get various errors like

provides a compile-time reference assembly for mscorlib on MonoAndroid,Version=v6.0, but there is no run-time assembly compatible with win.

error CS1703: Multiple assemblies with equivalent identity have been imported

Make sure your imports on all projects only contain what is shown in the example above and remove the Portable.Compatibility project from all projects. You don’t need it, but it does affect Resx files and possibly some other things.

Final Thoughts

I would stick with Profile Based PCL’s for the moment until some official guidance from the Xamarin Team is given on .NET Standard Library and a little more dust has settled. (Update 21/07/2016: Beta Release Cycle7 of Xamarin now includes official support for .NET Standard 1.6) Most likely the Xamarin Forms Nuget package will be updated in the future to this standard. You can have both .NET Standard and Profile Based PCL in the same Nuget, this might provide some needed relief during transition if possible, however not all package providers chose that route. AutoMapper certainly decided .NET Standard all the way and you have to upgrade your project to .NET Standard 1.1 or 1.3 in order to use the latest version.

While .NET Standard is a much better way to deal with API availability, this transition looks painful as some packages update and others take their time. Remember that once you have a .NET Standard Library a Profile Based PCL can’t reference it, hence you need to convert everything up the chain to .NET Standard.

I have started switching my production solutions to netstandard, now that I understand it a lot better and updated the above accordingly. AutoFac is also almost at a netstandard release, looks like major/common packages have been in transition for a long while. While you may hold off for now, it looks like the time is limited. They are challenges and I will keep updating this post as I continue to work through issues.

Microsoft MVP | Xamarin Certified Developer |
Exrin Creator | Xamarin Forms Developer | Melbourne, Australia

Related Posts

7 Comments

  1. Thomas Hagström

    Concerning RESX resources: I got this working by adding pre packages for Tools and ResourceManager:

    “System.Diagnostics.Tools”: “4.3.0-preview1-24530-04”
    “System.Resources.ResourceManager”: “4.3.0-preview1-24530-04”

    1. Adam Pedley

      Thanks Thomas. I also found that if you install Microsoft.NETCore.Portable.Compatibility you can edit RESX resources, however at the same time it causes issues with Xamarin.Android that I never found a way to resolve.

  2. Gianni Araco

    Hi Adam.
    I’m trying to move a Xamarin project (iOS, Android, WinPhone Silverlight) to Standard Libraries, but if I omit the Microsoft.NETCore.Portable.Compatibility pacakge I get various variants of this error:

    The type ‘Object’ is defined in an assembly that is not referenced. You must add a reference to assembly ‘mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e, Retargetable=Yes’.

    But if I do, as you say, I get in trouble with both the Android and iOS projects.

    Have you find any way to get rid of the mscorlib problem without the compatibility package?

    1. Adam Pedley

      Normally when you see these errors once you remove a Nuget package. Unload your android project, edit it and see if there are any NuGet package references near the bottom. If they are, remove them. Save and reload your project.

  3. Lance

    Can’t thank you enough for this example app you provided. I followed Oren Novotny’s blog on the same topic, but after 3-5 attempts with File > New > Project apps.. I couldn’t get builds to stop bugging out on me.

  4. Rafał

    Hi Adam, thank you for helpful article.
    You wrote:

    “you don’t need to define references to packages that your dependencies have a reference to, they are transitive”

    Are you sure about it? I am trying to build native Windows 8.1 project with referenced PCL netstandard1.1 that has references to another reference and I cannot use this reference in native project. Moreover this reference is not included in result binaries and I have runtime errors.
    After adding reference to native project it starts working.

Leave A Comment?