INTRODUCTION
I am building a class library which could be used by some legacy applications targetting .Net Framework 4.0 and new applications targetting .Net Framework 4.6.1
I am adding some database/Hibernate new code in the class library that requires .Net Framework 4.6.1. This new code is incompatible with .Net Framework 4.0 because the nuGet package FluentNHibernate 3.1.0 requires .Net Framework 4.6.1 and up. And legacy application does not require this functionnality.
WHAT I AM TRYING TO ACHIEVE
I am attempting to conditionnaly build the class library so one code base and the master git branch can be used to build a version compatible for either one or the other application.
So far, I have been able to:
- Define a constant indicating the target framework (FWK40)
- for use within .cs code to adjust code to target framework
- Conditionally define the targetted framework (TargetFrameworkVersion)
- Exclude files from build when not under the right TargetFrameworkVersion
Here is what the .CSPROJ looks so far (emphasis for the relevant adjustments):
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug.Net40|AnyCPU'">
<!-- Set target framework here -->
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\Debug.Net40\</OutputPath>
<!-- Define Build-time constant here -->
<DefineConstants Condition=" '$(TargetFrameworkVersion)' == 'v4.0'" >FWK40</DefineConstants>
</PropertyGroup>
<ItemGroup>
<-- Conditionally include .cs files here -->
<Compile Include="Database\GeneralSQL.cs" Condition="'$(TargetFrameworkVersion)' != 'v4.0'" />
<Compile Include="Database\NamingStrategy.cs" Condition="'$(TargetFrameworkVersion)' != 'v4.0'" />
<ItemGroup>
<ItemGroup>
<-- In THEORY conditionally include PackageReference here -->
<PackageReference Include="FluentNHibernate" Condition="'$(TargetFramework)' != 'net40'" >
<Version>3.1.0</Version>
</PackageReference>
</ItemGroup>
THE RESULT SO FAR
What is happenning, is I am getting a nuGet error saying:
NU1202: Package FluentNHibernate 3.1.0 is not compatible with net40 (.NETFramework,Version=v4.0). Package FluentNHibernate 3.1.0 supports:
Failed to restore C:\_projets\repos\TestSolution\TestLibrary\TestLibrary.csproj (in 19 ms).
NuGet package restore failed. Please see Error List window for detailed warnings and errors.
Not withstanding this error, the assemblies all are generated properly, the DLL Class Library itself, as well as an EXE Console application using that class library AND so far they run properly.
THE PROBLEM
I haven't been able to conditionnaly include nuGet a PackageReference.
AND The nuGet error still causes MSBuild.exe to fail, which prevents the CI/CD pipeline to work properly..
WHAT I HAVE TRIED
I have tried many many ways to get rid of nuget NU1202 error message.
#1 I have tried initially with other conditions based on $(TargetFrameworkVersion) which works througout the .csproj but to no avail.
#2 According to official documentation, nuGet ReferencePackage only supports conditions based on $(TargetFramework) adding-a-packagereference-condition as shown in the sample .csproj above. YET THIS STILL DOES NOT WORK.
I haven't been able to figure out so far what exactly the Property
TargetFramework
looks like. I ran MSBUILD.EXE in Verbosity level diagnostics, which dumps all the Properties, but TargetFramework wasn't listed (while others were)I have tried to "reverse" the condition
== 'net461'
so that if the expected value is incorrect, it won't be included and the error would disappear => no effect, errors still there
#3 I have tried to define myself the TargetFramework property
<!-- Set target framework here -->
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFramework>net40</TargetFramework>
- The outcome would be much worse!
- Visual Studio did not like it, the "Configuration Manager" broke down
- it would not allow to set a specific Configuration for a project.
- changing from Debug.Net40 to any other configuration (or loading the project) would show a nasty error message
Current solution contains incorrect configuration mappings. It may cause projects to not work properly
And the csproj was definitely not loaded properly either and project would be skip the build step.
WHERE I AM AT NOW
I am really stuck! Can't seem to find a way to make this work.
- I would hate to have to have a branch master40 and a branch master just to handle this.
- I would hate to have to have two csproj different files, unless I can somehow manage to share/include one into the other AND Visual Studio would not complain
The really really right thing would be to make the conditions on the ReferencePackage to actually work as intended.