Referencing a .NET Standard library from a Windows Class Library
Asked Answered
I

3

19

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.
Inspect answered 15/2, 2017 at 16:1 Comment(7)
What's the output when you run "dotnet restore"?Dilantin
Nothing useful I think, I've added it to the end of the question.Inspect
The Xenko editor uses the .NET Standard 4.0+ libraries in the Game Class Library, And then the.NET Framework 4.6.2 in the Windows main. I usually set them to target the highest available. That's an Open Source Graphics Game Engine being developed and allows setting the .NET Standard 1.0 and lower .NET Framework versions in both C# projects once opened in the Visual Studio 2013, 2015 IDE.Orthohydrogen
The .Net Standard libraries are 1.0 to 1.6 i can set, i just checked and can't change the comment in the last one.Orthohydrogen
I just tried lowering to .NET Standard 1.0 and .NET Framework 4.6.1, and will not compile 2 lines. { "supports": {}, "dependencies": { "Microsoft.NETCore.Portable.Compatibility": "1.0.1", "NETStandard.Library": "1.6.0" }, "frameworks": { "netstandard1.1": {} } } lowest i could go is 1.1Orthohydrogen
Don't force Visual Studio 2015 too much. Try VS2017.Kuenlun
I have seen this symptom where the Solution build targets did not include all the targes such as leaving out x86 or not including AnyCPU for every project. I was suspicous that the VS IDE somehow had a hint to an old build and confusd me that it was built - but it really wasnt. You might look in project fiels to see if an old assembly is refeerenced.Sundial
H
18

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).

Hyperion answered 20/2, 2017 at 14:6 Comment(4)
Thank you for the detailed explanation, I guess I'll just go wait for the Visual Studio 2017 to be released. After all it's just two weeks from now.Inspect
And then— after that, it's a just few weeks before they release patches to get it somewhat bug-free. ;)Hyperion
Answer is now out of date because of the move to csproj for .net standardHonestly
@Honestly this is true, but many people still use the old (now legacy?) project.json, so the answer is still relevant.Hyperion
C
18

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"/>.

Castanon answered 21/2, 2017 at 10:12 Comment(0)
A
2

You can not use some libraries in PCL projects because it is not built as a PCL and it is not cross platform. Some namespace is unavailable in PCL projects and it is not listed here.

The following assemblies are available within a Portable Class Library project:

mscorlib.dll

System.dll

System.Core.dll

System.Xml.dll

System.ComponentModel.Composition.dll

System.Net.dll

System.Runtime.Serialization.dll

System.ServiceModel.dll

System.Xml.Serialization.dll

System.Windows.dll (from Silverlight)

However, not all of these assemblies are supported on all platforms.

Anjelicaanjou answered 18/2, 2017 at 7:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.