I'm trying to wrap my head around the NuGet package system. Recently I released a class library for NuGet, targeting only .NET Framework 4.5.2, but as of demand, I decided to create a new class library targeting .NETStandard 1.4.
Here's where I get lost. Is is possible for me to target multiple frameworks in a single NuGet package, taking this scenario of having two different projects?
Would it make sense for me to remove the .NET Framework 4.5.2 project, and replace it with my .NETStandard 1.4 project? The code is 100% the same.
Any suggestions or best practices to navigate through such a scenario?
If you need to support .NET Framework 4.5.2, you'd need to lower the version of .NET Standard to 1.2 as per compatibility matrix since .NET Standard 1.4 packages can only be used on .NET Framework 4.6.1+.
If this is not possible for you, you can multi-target your project so that the same project is built for a version of .NET Standard and .NET Framework and packages into the same NuGet package. .NET Framework projects referencing that package will prefer the .NET Framework dll over the .NET Standard dll in the same package.
You can do this by changing the .NET Standard project from
<TargetFramework>netstandard1.4</TargetFramework>
to
<TargetFrameworks>net452;netstandard1.4</TargetFrameworks>
By changing the property to TargetFrameworks (plural), the project will now be built twice - once per specified framework.
Related
I'm just getting started in NuGet packages creation thing and I know how to create a NuGet package for .NET Framework and .NET Core applications but I'm not sure if there any way of creating the NuGet package where it will support both .NET Core as well as .NET Framework. But I've seen the NuGet packages that works with both .NET Core and Framework.
For example, if I open .nupkg file of NewtonSoft.JSON I see the something like this.
Newtonsoft.JSON hierarchy
And yes, currently I'm developing my packages using .NET Framework 4.5, so it supports both. But I want a native support for that package not with the backwards compatibility in my .NET Core applications. Also, I don't want to develop using .NET Standard, because in Newtonsoft.JSON package it looks like they are using the .NET Standard.
.NET Standard is a specification that has multiple implementations including .NET Framework and Core/5/6.
If you want to support Framework 4.5 in addition to core the most up-to-date version you can target is Standard version 1.1.
ref: https://learn.microsoft.com/en-us/dotnet/standard/net-standard?tabs=net-standard-1-1
In one of my .NET Framework projects, I introduced a new .NET Standard 2.0 project. This project has dependencies on some existing .NET Framework projects. I was wondering if this is right to do.?
The reason I added a .NETStandard project is that we have plans to move the whole repository to .NET Core / Standard. Hence I thought, the new project we add can target .NET Standard. With .NET Standard project I get the new SDK style project file, package references, etc by default.
The consuming application is still .NET Framework.
Do I have to retarget the new project to .NET Framework 4.7.2 so that the project will have the above SDK style project file and package references but targets .NET Framework 4.7.2 now. It will then be as easy as changing the target framework when we move to .NET Core?
Depends on your purpose of introducing the Standard 2.0 project. Normally, you make a Standard when you need it to be accessible both from .NET Framework and Core. In your case, your Standard project won't be operable from Core under macOS or Linux.
Yes, this can be done.
https://learn.microsoft.com/en-us/dotnet/standard/net-standard?tabs=net-standard-2-0
.NET Framework compatibility mode
Starting with .NET Standard 2.0, the .NET Framework compatibility mode was introduced. This compatibility mode allows .NET Standard projects to reference .NET Framework libraries as if they were compiled for .NET Standard. Referencing .NET Framework libraries doesn't work for all projects, such as libraries that use Windows Presentation Foundation (WPF) APIs.
This is necessary as an intermediate step for some projects, but in order to get to your final goal you will of course have to go all in on .net core which will require updating those projects not to use framework or they will crash at runtime.
Setup
Say I have a .Net Standard 2.0 class library project and I add a Nu NuGet package that is compatible with .Net Standard 2.0 to it.
I then reference that class library project from both a .Net Framework console project and a .Net Core console project.
To restate with a picture:
Question
How does each of the console applications deal with getting the right NuGet code for their type of application?
Notes
Note: I tried this using Microsoft.Extensions.DependencyInjection, and it works fine in the .Net Core 3.1 console app, but throws a "File Not Found" exception in the .Net Framework 4.7.2 console app (looking for the Dependency Injection DLL). This leads me to believe that .Net Standard 2.0 NuGets are really .Net Core NuGets...
Note to the Note: I am trying to understand what happens here, not fix the "File Not Found" issue. (That is easily fixable by referencing the Microsoft.Extensions.DependencyInjection NuGet in the .Net Framework 4.7.2 console app).
In your scenario two different package resolution startegies are used. There is the old way of managing packages with packages.config and the new way with PackageReferences. There is also the old project format of .NET Framework projects and the new SDK-style format that was introduced for .NET Core, but is also usable in .NET Framework applications.
With the old project format that is still used by most existing .NET Framework applications regardless of packages.config or PackageReference, the .NET Framework Console application is only able to access the class library, but not the assemblies of its referenced NuGet package, because it is not a direct reference but via your library, hence indirect. This is als called a transitive dependency.
In the new SDK-style project format with PackageReference, this is fundamentally different. There, transitive dependencies are possible. This means, that your .NET Framework console application can access the class library project, as well as its referenced assemblies via the NuGet package.
The SDK-style format with PackageReference is the default for .NET Core projects, so they support transitive dependencies out of the box. Only with the old project format you have to add NuGet packages manually, because it cannot access the transitive dependency through the class library. You can migrate existing .NET Framework projects to the new SDK-style format, to enable the same behavior as in .NET Core.
I have an old-style C# WPF project file. It is a .NET Framework 4.7.2 project. I want to reference a NuGet library that has builds for .NET Standard 2.0 and .NET Framework 4.5.1. An example of this would be morelinq.
As I understand it, .NET Framework 4.7.2 fully implements the .NET Standard 2.0 API. Therefore I would like my project to reference the .NET Standard 2.0 build in the NuGet package instead of the .NET Framework 4.5.1 build. The benefit of this would be that the .NET Standard 2.0 version of morelinq does not have additional dependencies, e.g. on System.ValueTuple.
However, when I add the NuGet package, it defaults to referencing the .NET Framework 4.5.1 build and hence, includes its additional dependencies.
This is only one of a few such cases. So at the moment it seems, to me at least, that I'm references many unnecessary additional dependencies that could be avoided.
(My apologies if this is a duplicate. I did try searching first.)
I really wanted to be a good citizen... copied all my classes to .net standard 1.6 libraries. Just to find out that my test DLL can't use it. I get the following error
Project X targets '.NETStandard,Version=v1.6'. It cannot be referenced by a project that targets '.NETFramework,Version=v4.6.1'.
Of course, when I check .Net Standard (https://learn.microsoft.com/en-us/dotnet/articles/standard/library) it says that with 1.6 it can target 4.6.1.
I tried 4.6.2 without better luck. I installed the .net standard 1.6.1 NuGet package. Anyway, you guys are awesome, I'm sure you'll tell me which stupid mistake I'm making that is preventing me from doing something as basic as running unit tests with a .net standard library.
Thanks
P.S. I did find a work around (kind of) by using a .net core unit test project instead of a .net framework one. It doesn't solve my problem, so I can't mark that as an answer, but at least I can go back to coding...
You need to upgrade to .Net Core SDK 2.x+
Once that is installed restart your machine and you should be able to reference NetStandard 1.6 in .Net Framework 4.6.1+
With .Net Core SDK 1.x you can only reference Net Standard 1.5 in .Net Framework 4.6.2
Best would be to upgrade your Net Standard project to version 2.0 if you can.
In case of errors with similar titles that are targeting different versions of .net framework, this usually means that you need to (install if already not and) change the target of your project to newer/newest version of .net framework to comply with the project that targets newer .net standard.