升级包参考时,如何编写更新绑定重定向的NuGet包?

时间:2019-01-02 16:08:03

标签: nuget assembly-binding-redirect

我们使用VS 2017并以旧方式使用NuGet软件包。到目前为止,我们尚未使用PackageReference。

通过VS中的NuGet管理器更新NuGet包引用时,相应的程序集绑定重定向不会自动更新-我们必须手动进行。

因此,我想这取决于软件包是通过tools \ install.ps1脚本来处理它的。现在,我想我知道如何实现它,但是我不想发明轮子。当然代码已经存在于某个地方,但是在哪里?

说明

我们的应用程序经过了严格的签名,目前以.NET 4.5.2为目标(即将升级到4.7.2)。我们使用packages.config。

我需要解释发生了什么。场上有三名球员:

  1. 工具-DbUpgrade
  2. 工具插件Api-DbUpgradeApi
  3. 插件Api的实现-LogDbUpgradeProgress

让我们检查DbUpgradeApi软件包。它的3个版本与我们有关:

  1. 根据其编译LogDbUpgradeProgress的版本- A
  2. DbUpgrade编译所依据的版本- B
  3. DbUpgradeApi的最新版本- C

DbUpgrade工具在运行时加载插件LogDbUpgradeProgress。绑定重定向是必需的,因为 A B 不同(并且由于代码已签名,因此目前不执行任何操作)

如果 C 高于 B ,则我们应在DbUpgrade中更新对DbUpgradeApi的引用。但是,这样做必须伴随着更新绑定重定向。这就是这个问题的本质。

1 个答案:

答案 0 :(得分:1)

好吧,所以我只花了最后一个小时的测试,我不需要做我认为特别适合绑定重定向工作的任何事情。

但是首先,您确定需要绑定重定向吗? .NET Core不需要它。如果您使用的是.NET Framework,但使用PackageReference的项目在构建时已解决,则您的app.config不需要在使用代码签入的版本中进行绑定重定向,而是在构建和检查时[您的exe名称] .config文件确实具有绑定重定向。另外,绑定重定向仅在程序集具有强命名时才重要。如果您未对程序集签名,则不需要绑定重定向。

下面是我使用packages.config在控制台应用程序中创建获取绑定重定向的复制品的步骤。

  1. 创建一个空文件夹开始。我使用了dotnet new slndotnet net nugetconfig来生成一个新的sln和nuget.config文件。我编辑了nuget.config文件,将文件夹localFeed添加为源,并将globalPackagesFolder设置为gpf,这样我就不会用测试软件包污染我真正的全局软件包文件夹。还使用sn -k snk.snk创建了一个强名称密钥。
  2. 创建第一个测试类库。 dotnet new classlib -n someLib。我编辑了Class1.cs,将类名更改为SomeClass,并添加了一个属性,该属性重新定义了“版本1”的值。使用Visual Studio将snk.snk设置为签名密钥。 dotnet pack生成包的V1。然后,我编辑了SomeClass,将消息更改为“ Version 2”,然后运行了dotnet pack /p:version=2.0.0。最后,将nuget.exe add -source localFeed someLib\bin\Debug\someLib.1.0.0.nupkg再次用于nupkg的v2。
  3. 创建第二个测试类库dotnet new classlib -n anotherLib,并将签名密钥设置为snk.snk。将Class1.cs更改为AnotherClass,并添加了属性public string Message => new someLib.SomeClass().Message;。在csproj中添加了对someLib 版本1 的引用,然后构建,打包并使用nuget.exe将nupkg添加到localFeed。
  4. 打开Visual Studio并创建一个.NET Framework控制台应用程序。添加了对anotherLib的引用,该引用自动引入了someLib的v1版本。将someLib的引用升级到v2,并确认packages.config现在具有someLib的绑定重定向。
  5. 创建了另一个.NET Framework控制台应用程序,并执行了与步骤3相同的操作,但是这次使用的是PackageReference而不是packages.config。项目app.config没有绑定重定向,但是构建后的bin文件夹中的.config文件没有。

edit:以下是理解NuGet / MSBuild绑定重定向行为的重要部分:在第3步和第4步中,如果我仅添加对anotherLib的引用,则不会创建绑定重定向,因为所有组装引用someLib引用相同的版本。仅通过使我的控制台应用程序引用与someLib使用的anotherLib不同的版本,才能创建绑定重定向。

在具有插件的应用程序中,构建应用程序程序集将没有绑定重定向,因为它是编译命令行中使用插件协定dll的唯一程序集,因此不需要绑定重定向。构建插件程序集时,只有插件依赖于插件合同dll,因此再次没有冲突,因此没有绑定重定向。如果将所有dll复制到单个文件夹中,则所需版本可能会发生冲突,但这是部署时间问题,而不是构建/编译时间问题,因此构建工具可能无济于事。解决此问题的一种方法是从应用程序程序集添加对插件项目的引用。通过这种方式,构建工具可以在编译时看到使用了两个不同版本的插件协定dll,因此可以创建绑定重定向。这仅在您构建应用程序集时才有效。如果应用只是给您的二进制文件,那么更改绑定重定向将成为部署时的责任,因此开发/构建工具可能无济于事。