Tips for Upgrading to .NET Standard 2.0

.NET Version Overview

  • .NET Standard 2.0 is a specification for a set of cross-platform APIs that all platform implementations of that standard must support.
  • .NET Core 2.0 is a cross-platform implementation of that .NET Standard 2.0
  • .NET Framework is a Windows-only implementation of various .NET APIs
  • .NET Framework 4.7.1 fully implements .NET Standard 2.0

System.* Packages Dead-Ended from .NET Core 2.0

Referencing .NET Standard 2.0 Libraries

  • Full .NET Framework 4.7.1 class libraries can reference any .NET Standard 2.0 (or earlier) library
  • However, a .NET Standard 2.0 library cannot necessarily reference and use a full .NET Framework class library - because that library may no comply with the .NET Standard.
  • It is estimated that at the time of the release of .NET Core 2.0, approximately 70% of existing NuGet packages can be used without an issue - BUT you won’t know there is an issue without thorough testing with that library!
  • Microsoft has decided to emit a nice ugly compiler warning and warning signal against a reference in the Solution Explorer when this is the case.
  • Recommendation: Use a full .NET Framework class library if you have references to any non .NET Standard class libraries - to avoid the compiler warning and ensure that the library does not have compatibility issues.
  • .NET Framework 4.6.1 with the .NET Core 2.0 SDK installed also supports .NET Standard 2.0 - but due to the way that the libraries are packaged, this can cause assembly binding problems - so better to target 4.7.1 from the start.
    • For example:
      • When running under .NET Core 2, the Tuple type is in assembly: System.ValueTuple, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e.
      • When running under .NET Framework 4.6.1, the Tuple type is in: System.ValueTuple, System.ValueTuple, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51.
      • But, when starting with a .NET Framework 4.6.1 application that uses a .NET Standard 2.0 library, the .NET Standard 2.0 code wants: System.ValueTuple, Version=0.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
    • If your application targeted 4.6.1 and .NET Framework 4.7.1 was later installed, any referenced .NET Standard libraries may experience System.TypeLoadException exceptions. The workaround being to re-target your application to 4.7.1.

.NET Framework Libraries & Automatic Assembly Binding Redirects

  • By default, assembly binding redirects aren’t added to full .NET Framework class library projects.
  • This is problematic for unit testing projects as they are essentially like applications
  • Add the following into the .csproj:
    1<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
    2<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
    
  • And then remove all the manual binding redirects from the app.config file
  • See also: How to enable and disable automatic binding redirection

Compiler warnings

  • With .NET Framework libraries referencing .NET Standard 2.0 libraries, Microsoft.Extensions.DependencyInjection.Abstractions causes a compiler warning:
    • “Resolved file has a bad image, no metadata, or is otherwise inaccessible. The system cannot find the path specified. (Exception from HRESULT: 0x80070003)”
    • This should be fixed in a future .NET SDK update: Issue 1544 and Issue 1548