如何在构建期间控制 nuget 包依赖项的输出
How to control output of a nuget package dependencies during build
我想在我的应用程序中支持向后兼容性。
简单地说 - 一个应用程序需要使用不同版本的 dll,具体取决于应用程序在运行时获得的标志。
我简化了所有内容并创建了一个包含 2 个项目的测试解决方案。
每个项目都有自己的相同 nuget 包版本。
我选择了 System.Drawing.Common
因为它没有依赖关系。
ClassLibrary1
包含 System.Drawing.Common
版本 4.5.0
。
ClassLibrary2
包含 System.Drawing.Common
版本 6.0.0
。
两个项目有相同的输出路径:
<OutputPath>..\DEBUG\</OutputPath>
当我构建解决方案时,我的输出文件夹中只有一个 System.Drawing.Common.dll
:
因为两个 dll 同名,只是版本不同。
下图所需的行为:
根据版本将nuget包依赖分发到不同的文件夹中。
根据版本给nuget包依赖加上后缀。
这个想法是控制 nuget 包依赖项的输出。
你知道我该如何实现吗?
P.S。所有其他逻辑 - 根据版本等解决依赖关系超出了这个问题的范围。
这不是包解析在 .NET 中的工作方式,您会得到每个包的一个版本,这是在恢复时决定的。
如果您有一个非常小众的问题,可能会有一些时髦的选择,但听起来您可能正在尝试以一种不常见的方式解决一个常见问题,这通常不是一个好主意。
通常,对于向后兼容性问题,责任在于图书馆的出版商而不是图书馆的消费者,以通过不进行重大 API 更改来确保一切正常。
这是可能的。
首先,您需要将 GeneratePathProperty
添加到 csproj
文件
中的 PackageReference
元素
<ItemGroup>
<PackageReference Include="System.Drawing.Common">
<Version>4.5.0</Version>
<GeneratePathProperty>true</GeneratePathProperty>
</PackageReference>
</ItemGroup>
它允许我们使用包含 nuget 包路径的 $(PkgSystem_Drawing_Common)
变量。
然后我们需要创建一个msbuild targets
文件
<?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>
这里使用 xpath
我们从 project.assets.json
文件 select 版本并将其保存在 NugetPackageVersion
变量中。 Exec copy
用于将 dll 复制到具有特定前缀的特定位置,该前缀包含来自 NugetPackageVersion
变量的值。
最后您需要将 msbuild targets
文件包含到项目中
<Import Project="CopyDll.targets" />
我想在我的应用程序中支持向后兼容性。 简单地说 - 一个应用程序需要使用不同版本的 dll,具体取决于应用程序在运行时获得的标志。
我简化了所有内容并创建了一个包含 2 个项目的测试解决方案。 每个项目都有自己的相同 nuget 包版本。
我选择了 System.Drawing.Common
因为它没有依赖关系。
ClassLibrary1
包含 System.Drawing.Common
版本 4.5.0
。
ClassLibrary2
包含 System.Drawing.Common
版本 6.0.0
。
两个项目有相同的输出路径:
<OutputPath>..\DEBUG\</OutputPath>
当我构建解决方案时,我的输出文件夹中只有一个 System.Drawing.Common.dll
:
因为两个 dll 同名,只是版本不同。
下图所需的行为:
根据版本将nuget包依赖分发到不同的文件夹中。
根据版本给nuget包依赖加上后缀。
这个想法是控制 nuget 包依赖项的输出。 你知道我该如何实现吗?
P.S。所有其他逻辑 - 根据版本等解决依赖关系超出了这个问题的范围。
这不是包解析在 .NET 中的工作方式,您会得到每个包的一个版本,这是在恢复时决定的。
如果您有一个非常小众的问题,可能会有一些时髦的选择,但听起来您可能正在尝试以一种不常见的方式解决一个常见问题,这通常不是一个好主意。
通常,对于向后兼容性问题,责任在于图书馆的出版商而不是图书馆的消费者,以通过不进行重大 API 更改来确保一切正常。
这是可能的。
首先,您需要将 GeneratePathProperty
添加到 csproj
文件
PackageReference
元素
<ItemGroup>
<PackageReference Include="System.Drawing.Common">
<Version>4.5.0</Version>
<GeneratePathProperty>true</GeneratePathProperty>
</PackageReference>
</ItemGroup>
它允许我们使用包含 nuget 包路径的 $(PkgSystem_Drawing_Common)
变量。
然后我们需要创建一个msbuild targets
文件
<?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>
这里使用 xpath
我们从 project.assets.json
文件 select 版本并将其保存在 NugetPackageVersion
变量中。 Exec copy
用于将 dll 复制到具有特定前缀的特定位置,该前缀包含来自 NugetPackageVersion
变量的值。
最后您需要将 msbuild targets
文件包含到项目中
<Import Project="CopyDll.targets" />