I would like to support backward compatibility in my application. Simply saying - one app needs to work using different versions of a dll depending on a flag which the app get's during runtime.
I've simplified everything and created a test solution with 2 projects in it. Each project has it's own version of the same nuget package.
I picked System.Drawing.Common
cause it has no dependencies.
ClassLibrary1
contains System.Drawing.Common
of version 4.5.0
.
ClassLibrary2
contains System.Drawing.Common
of version 6.0.0
.
Both projects have same output path:
<OutputPath>..\DEBUG\</OutputPath>
When I build my solution I get just one System.Drawing.Common.dll
in my output folder:
Cause both dlls have one name and only version is different.
The desired behavior on the pictures below:
Distribute the nuget package dependencies into different folders according to versions.
Add suffix to the nuget package dependencies according to versions.
The idea is in controlling output of the nuget package dependencies. Do you have any idea how I can achieve that ?
P.S. all other logic - resolving dependencies according versions etc is out of scope of this question.
It's possible.
First you need to add GeneratePathProperty
to PackageReference
element in csproj
file
<ItemGroup>
<PackageReference Include="System.Drawing.Common">
<Version>4.5.0</Version>
<GeneratePathProperty>true</GeneratePathProperty>
</PackageReference>
</ItemGroup>
It allows us using $(PkgSystem_Drawing_Common)
variable which contains a path to the nuget package.
Then we need to create a msbuild targets
file
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="CopyNugetDll" BeforeTargets="BeforeCompile" Outputs="System.Drawing.Common.dll">
<XmlPeek XmlInputPath="$(ProjectPath)" Query="Project/ItemGroup/PackageReference[@Include='System.Drawing.Common']/Version/text()">
<Output TaskParameter="Result" PropertyName="NugetPackageVersion" />
</XmlPeek>
<ItemGroup>
<NugetrDll Include="$(PkgSystem_Drawing_Common)\lib\net461\System.Drawing.Common.dll" />
</ItemGroup>
<Message Text="Copying @(NugetrDll) to $(OutDir)" Importance="high" />
<Exec Command="copy $(PkgSystem_Drawing_Common)\lib\net461\System.Drawing.Common.dll $(OutDir)\System.Drawing.Common.$(NugetPackageVersion).dll" />
</Target>
</Project>
Here using xpath
we select version from project.assets.json
file and save it in NugetPackageVersion
variable. Exec copy
is used to copy the dll to a specific location with a specific prefix which contains a value from NugetPackageVersion
variable.
Lastly you need to include msbuild targets
file to a project
<Import Project="CopyDll.targets" />