简体   繁体   中英

How to control output of a nuget package dependencies during build

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:

  1. Distribute the nuget package dependencies into different folders according to versions. 期望的输出

  2. 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?

PS all other logic - resolving dependencies according versions etc is out of scope of this question.

This just isn't how package resolution works in .NET, you get one version of each package which is decided at restore time.

There may be some funky options if you have a very niche problem, but it sounds like maybe you're trying to solve a common problem in an uncommon way which is generally a bad idea.

Typically for the problem of backwards compatibility the onus is on the publisher of the library rather than the consumer of the library to make sure it all works by not making breaking API changes.

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" />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM