Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Referencing a .NET Standard library from a Windows Class Library

There are two projects in my solution currently: a Windows Class Library (targeting .NET Framework 4.6.1) and another class library that targets .NET Standard 1.3. I'm using Visual Studio 2015 Update 3.

I've added a reference to the .NET Standard project from the other project and it appears in the list of references, but I can't see any of the classes or namespaces from the referenced library when I want to use them (even though the referenced library was successfully built and has no errors).

This is the project.json for the .NET Standard library project:

{
  "version": "1.0.0-*",

  "dependencies": {
    "NETStandard.Library": "1.6.0"
  },

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

I thought that .NET 4.6.1 projects can use .NET Standard 1.3 libs, and I even tried to use lower versions (1.0), but the result is the same. What am I missing here?

If I run

dotnet restore

it also works fine:

log  : Restoring packages for C:\Users\Zsolt\Documents\Visual Studio 2015\Projects\PWB\PWBSpreadsheet.Entities\project.json...
log  : Restoring packages for C:\Users\Zsolt\Documents\Visual Studio 2015\Projects\PWB\PWBSpreadsheet.Parser\project.json...
log  : Writing lock file to disk. Path: C:\Users\Zsolt\Documents\Visual Studio 2015\Projects\PWB\PWBSpreadsheet.Parser\project.lock.json
log  : C:\Users\Zsolt\Documents\Visual Studio 2015\Projects\PWB\PWBSpreadsheet.Parser\PWBSpreadsheet.Parser.xproj
log  : Restore completed in 408ms.
log  : Writing lock file to disk. Path: C:\Users\Zsolt\Documents\Visual Studio 2015\Projects\PWB\PWBSpreadsheet.Entities\project.lock.json
log  : C:\Users\Zsolt\Documents\Visual Studio 2015\Projects\PWB\PWBSpreadsheet.Entities\PWBSpreadsheet.Entities.xproj
log  : Restore completed in 417ms.
like image 987
Bedford Avatar asked Feb 15 '17 16:02

Bedford


People also ask

What is class library with reference to net framework?

The Framework class library (FCL) is a comprehensive collection of reusable types including classes, interfaces and data types included in the . NET Framework to provide access to system functionality. The . NET FCL forms the base on which applications, controls and components are built in . NET.

What is the difference between class library .NET standard and class library .NET Core )?

Net standard has a higher version then more APIs/inbuilt library like “System. data” are available. So based on project requirements . Net standard library needs to be created.

Can you reference .NET Core from .NET standard?

NET Core wouldn't be able to reference a . NET Standard project.


2 Answers

Referencing a .NET Core project from a Windows Class Library should be possible. However—the .NET Standard library is not "directly compatible" with previous versions of .NET Framework, i.e., 4.6.1 or below. The .NET Standard library is a package with components that already exist within the .NET Framework (4.6.1 for instance). The difference is that the .NET Standard library is built for the cross-platform .NET Standard framework.

You may, target multiple frameworks under the "frameworks" section in your project.json-file.

While doing so, you should also move the "NETStandard.Library"-dependency directly under the "netstandard1.x"-framework.

Example project.json

{
  "version": "1.0.0-*",

  "dependencies": { },

  "frameworks": {
    "net461": { },
    "netstandard1.3": {
      "dependencies": {
        "NETStandard.Library": "1.6.0"
      },
      "imports": "dnxcore50"
    }
  }
}

This ensures that you do not include any superfluous dependencies towards the NET Standard library as these dependencies will only get included when building towards the NET Standard framework. If built against .NET Framework 4.6.1, these dependencies are omitted. This is fine—as these dependencies are already part of the .NET Framework (as described above).

Now say for instance you want to reference something that is not part of the .NETStandard library, but part of the .NET 4.6.1 framework. A common case for this at my workplace is System.ComponentModel.DataAnnotations. It is part of the .NET Framework, but a separate package for the .NET Standard framework.

You will then have to reference it as a framework assembly for "net461", but as a dependency for the "netstandard1.x" framework.

Example project.json

"frameworks": {
  "net461": {
    "frameworkAssemblies": {
      "System.ComponentModel.DataAnnotations": "4.0.0.0"
    }
  },
  "netstandard1.3": {
    "dependencies": {
      "NETStandard.Library": "1.6.0",
      "System.ComponentModel.Annotations": "4.1.0"
    },
    "imports": "dnxcore50"
  }
}

As @meziantou describes:

Referencing .NET Standard in a project that targets the full framework does not work correctly yet.

I just tested it in Visual Studio 2015, and I can confirm—the reference gets added, but you cannot use any component of the referenced library.

If you don't have Visual Studio 2017 installed, the only solution I can think of is to dotnet pack your project and publish it to a NuGet-feed. You may set up a local NuGet feed for this purpose.

Then simply use the Install-Package cmdlet in the NuGet package manager console.

Install-Package <your-package> -v 1.0.0-<x>

The package-manager will reference the correct version of the package (.NET 4.6.1).

like image 161
mausworks Avatar answered Sep 21 '22 14:09

mausworks


Referencing .NET Standard in a project that targets the full framework does not work correctly yet. Instead, your project must target multiple frameworks.

If you are using the new tooling (with VS 2017), i.e. the csproj project format, you can set multiple target in the TargetFrameworks tag:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>netstandard1.3;net46</TargetFrameworks>
  </PropertyGroup>
</Project>

If you need to, you can set different dependencies for each target:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>netstandard1.3;net46</TargetFrameworks>
  </PropertyGroup>

  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard1.3'">
    <PackageReference Include="Microsoft.Win32.Primitives" Version="4.3.0" />
    <PackageReference Include="System.Collections" Version="4.3.0" />
    <PackageReference Include="System.Runtime.InteropServices" Version="4.3.0" />
  </ItemGroup>

  <ItemGroup Condition="'$(TargetFramework)' == 'net46'">
    <PackageReference Remove="NETStandard.Library" />
  </ItemGroup>
</Project>

By default the NETStandard.Library is automatically added. If you want to remove it, use PackageReference Remove="NETStandard.Library"/>.

like image 38
meziantou Avatar answered Sep 22 '22 14:09

meziantou