Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you multi-target a .NET Core class library with csproj?

When .NET Core still used the project.json format, you could build a class library targeting multiple frameworks (e.g. net451, netcoreapp1.0).

Now that the official project format is csproj using MSBuild, how do you specify multiple frameworks to target? I am trying to look for this from the project settings in VS2017, but I am able to only target a single framework from the .NET Core frameworks (it doesn't even list the other full .NET Framework versions which I do have installed):

enter image description here

like image 241
Gigi Avatar asked Mar 12 '17 13:03

Gigi


People also ask

Can you have multiple target frameworks?

For SDK-style projects, you can configure support for multiple targets frameworks (TFM) in your project file, then use dotnet pack or msbuild /t:pack to create the package. nuget.exe CLI does not support packing SDK-style projects, so you should only use dotnet pack or msbuild /t:pack .

What is .NET Framework multi targeting pack?

This multi-targeting pack installs new reference assemblies, IntelliSense files, and other supporting files. The target frameworks added by this update to Microsoft Visual Studio for projects to use are ". NET Framework 4.0. 3" and ".

Can we use .NET core library in .NET Framework?

The Answer is NO. We cannot use . NET Framework Base Class Library in . NET Core applications, because of compatibility issues.


1 Answers

You need to manually edit the project file and add s to the default TargetFramework and basically change it to TargetFrameworks. Then you mention the Moniker with a ; separator.

Also you can put the Nuget package references in a conditional ItemGroup manually or using VS Nuget Package Manager.

Here is what your .csproj should look like:

<Project Sdk="Microsoft.NET.Sdk">   <PropertyGroup>     <TargetFrameworks>netstandard1.6;net452</TargetFrameworks>   </PropertyGroup>    <ItemGroup Condition="'$(TargetFramework)' == 'net452'">     <PackageReference Include="Microsoft.Azure.DocumentDB">       <Version>1.12.0</Version>     </PackageReference>   </ItemGroup>    <ItemGroup Condition="'$(TargetFramework)' == 'netstandard1.6'">     <PackageReference Include="Microsoft.Azure.DocumentDB.Core">     <Version>1.1.0</Version>     </PackageReference>   </ItemGroup> </Project> 

Another workaround I do these days because of missing documentation is that I create a project in VS2015 and form the project.json using the available documentation and intellisense, then open the solution in VS2017 and use the built-in upgrade. I will then look at the csproj file to figure out how to make that configuration happen.

Multi-targeting more esoteric targets without a Moniker:

Microsoft:

PCLs are not recommended+

Although PCLs are supported, package authors should support netstandard instead. The .NET Platform Standard is an evolution of PCLs and represents binary portability across platforms using a single moniker that isn't tied to a static like like portable-a+b+c monikers.

If you want to target a Portable Profile it doesn't have a predefined moniker so Portable Profiles also can't infer TargetFrameworkIdentifier, TargetFrameworkVersion, and TargetFrameworkProfile. Also a compiler constant isn't defined automatically. Finally you have to add all assembly references none are provided by default.

This Example below is taken from a project that used the dynamic keyword so it additionally needed the Microsoft.CSharp assembly, thus you can see how it's references for different targets.

<Project Sdk="Microsoft.NET.Sdk">   <PropertyGroup>     <TargetFrameworks>netstandard1.5;net40;portable40-net45+sl5+win8+wp8</TargetFrameworks>   </PropertyGroup>    <PropertyGroup Condition="'$(TargetFramework)'=='portable40-net45+sl5+win8+wp8'">     <TargetFrameworkIdentifier>.NETPortable</TargetFrameworkIdentifier>     <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>     <TargetFrameworkProfile>Profile158</TargetFrameworkProfile>     <DefineConstants>$(DefineConstants);PORTABLE158</DefineConstants>   </PropertyGroup>    <ItemGroup Condition="'$(TargetFramework)'=='netstandard1.5'">     <PackageReference Include="Microsoft.CSharp" Version="4.3.0" />     <PackageReference Include="System.ComponentModel" Version="4.3.0" />   </ItemGroup>    <ItemGroup Condition="'$(TargetFramework)'=='net40'">     <Reference Include="Microsoft.CSharp" />   </ItemGroup>    <ItemGroup Condition="'$(TargetFramework)'=='portable40-net45+sl5+win8+wp8'">     <Reference Include="Microsoft.CSharp" />     <Reference Include="System" />     <Reference Include="System.Core" />     <Reference Include="System.Windows" />   </ItemGroup> </Project> 
like image 61
Aboo Avatar answered Oct 07 '22 02:10

Aboo