Home > Enterprise >  TargetFrameworks in .NET Core
TargetFrameworks in .NET Core

Time:09-09

We are upgrading our project to .NET 6 from .NET Framework 4.5. We have a windows form application. Many of windows form commands has been depriciated in .NET 6. So to tackle this, I changed one of the Windows Forms project in the solution from:

<PropertyGroup>
   <TargetFramework>net6.0-windows</TargetFramework>
</PropertyGroup>

to

<PropertyGroup>
   <TargetFrameworks>net45;net6.0-windows</TargetFrameworks>
</PropertyGroup>

Now after changing this, I get the below error:

Project <another_project> targets 'net6.0-windows'. It cannot be referenced by a project that targets '.NETFramework,Version=v4.7.2'.

I understand why another_project is throwing this error message which is because the another_project is referenced in this Windows Form project and another_project's TargetFramework is .NET 6. So, I can change the TargetFramework for another_project to include .NET 4.5 as well.

But my question is, if I change this TargetFramework to TargetFrameworks and add multiple Framework there, does that mean my project is not upgrading to .NET 6 completely. Since it's using .net45 to complie/build in those cases, where it's failing to build in .NET 6. How does TargetFrameworks work??

I found the below link also, TargetFramework vs. TargetFrameworks (plural). But was not much helpful to understand this.

CodePudding user response:

I'm assuming that you've upgraded your project files to SDK-style.

<TargetFrameworks>net45;net6.0-windows</TargetFrameworks> will effectively build your project twice - once for .NET 6.0 and once for .NET Framework 4.5.

(I'm not sure why your .NET Framework project is still targeting .NET 4.5 - I would have thought you should have retargeted it to 4.8 a long time ago...)

The output folders for these two targets will be:

For the DEBUG build:

  • \bin\Debug\net6.0-windows
  • \bin\Debug\net48

For the RELEASE build:

  • \bin\Release\net6.0-windows
  • \bin\Release\net48

Now if you want to reference one of those assemblies in another project, you're going to need to decide which to use, depending on the target framework for the dependent project.

In your case, it seems that you should be referencing the one in the "net6.0-windows" folder, so you should change your other project to reference that.

However, if you want the dependent project to ALSO be multi-targeted, you will need to change the hint path in the dependent project to use a compile variable to select the correct one.

For example, suppose your multi-targeted dependent project currently references a DLL using the following hint path:

<Reference Include="YourLibraryName">
    path to referenced dll\bin\debug\net45\YourLibrary.dll
</Reference>

(Where "path to referenced dll" is whatever path is needed to locate the library.)

Clearly that will only reference the DEBUG Net 4.5 version of the library. You want it to reference the correct debug or release version and the correct .Net 4.5 or .Net 6.0 version. To do that, you can change the hint path to:

<path to referenced dll>\bin\$(Configuration)\$(TargetFramework)\YourLibrary.dll

At build time, $(Configuration) is replaced with the correct DEBUG or RELEASE string, depending on whether you're building DEBUG or RELEASE.

Similarly, the $(TargetFramework) will be replaced with the current build target, taken from the <TargetFrameworks>net45;net6.0-windows</TargetFrameworks> setting - either "net45" or "net6.0-windows".

Doing this will cause the correct DLL to be chosen from your multi-targeted project on which this project depends.

Note that this only applies to references using HintPath as above. If you're using project references, things would be different.

Also note that it's also possible (and maybe better) to create a NuGet package which will handle the dependencies etc properly, but that's a whole different story.

CodePudding user response:

TargetFrameworks is used to build same project to multiple frameworks (so you have binary for each of them in output). It's usually used by libraries so they can be consumed by app targeted for different frameworks or, much less frequently, by apps, so they could be run on different machines.

I guess neither of theses is your cases. You just need to rework your app so it uses only features available in .NET Core.

CodePudding user response:

Since you have added both net45 and net6.0-windows to your project it means that it should be compliable for both frameworks (i.e. it will be compiled twice, for each of the target frameworks), but you are trying to add reference to net6.0 project, which can't be used from net45. You need to either upgrade both to net6.0 only, or add net45 to the another_project.

Though usually it is another way around (compared to what you are trying to do), you use multitargeting for library projects (i.e. another_project in this case if I understand correctly) and keep one version for the executables (i.e. WinForms project should keep it's version).

  • Related