如何构建/部署需要同一程序集的多个版本的项目?

djm*_*jmc 8 .net assemblies visual-studio

我正在使用conflict.dll版本6.2的项目,但该项目还使用了使用conflict.dll版本5.8的helper.dll.

我可以将6.2和5.8安装到GAC中,但我想让这个项目xcopy可以部署.我相信.net将在应用程序bin目录中搜索程序集,如下所示:\ bin\conflict.dll(6.2)\ bin\5.8\conflict.dll(5.8)

但是在这一点上,如何在项目中添加对两个版本的conflict.dll的引用,然后如何确保旧的conflict.dll部署到\ bin\5.8?我是否创建了构建操作,还是有其他方法?

谢谢

geo*_*osd 14

经过几个小时的搜索和诅咒,我找到了一个有效且易于实施的解决方案.

这个问题像所有其他的答案已经指出的是,以下所有必须满足:

  1. DLL的两个版本必须具有相同的名称,否则运行时将抱怨该名称与清单不匹配.
  2. 运行时必须能够在搜索路径中找到两个程序集.
  3. 由于重大更改,无法进行版本重定向.
  4. 在此示例中永远不会调用AppDomain.ResolveAssembly,因为程序集已经加载过一次.

解决方案如下,步骤如下:

  1. 在解决方案目录中创建一个目录,例如lib\使用此层次结构:

    lib\Conflict\v1\Conflict.dll
    lib\Conflict\v2\Conflict.dll

  2. 将以下内容添加到您的app/web.config:

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <dependentAssembly>
      <assemblyIdentity name="Conflict" publicKeyToken="111111111111" />
      <codeBase version="1.0.0.0" href="bin\Conflict\v1\Conflict.dll" />
      <codeBase version="2.0.0.0" href="bin\Conflict\v2\Conflict.dll" />
    </dependentAssembly>
  </assemblyBinding>
</runtime>
Run Code Online (Sandbox Code Playgroud)
  1. 使用以下命令添加post-build事件xcopy:

    xcopy $(SolutionDir)\ lib $(TargetDir)/ Y/S.

  2. 构建一次以便复制文件.单击"项目 - >显示所有文件".右键单击bin\Conflict并执行Include in Project(使您无法在代码中执行此操作).如果打包Web应用程序,则必须使用此文件.

完成!


And*_*tan 1

为了支持达林的答案,您当然需要消除此类多版本问题。他使用绑定重定向的解决方案是一个很好的解决方案 - +1。我可以提供一个解决方案,允许您在绝对必要时保留两者,但您必须编写一些代码。

这里唯一真正的问题是两个部署的文件名必须相同才能被加载程序默认选择。你可以非常可怕地作弊,简单地部署 5.8 dll,这样Conflict.exe它就可以并排放置Conflict.dll(和更新的),你会发现它可以工作。

另外,通过 Darin 的回答中的链接,您将进入MSDN 关于探测的主题。根据此内容,您可以简单地将 5.8 dll 部署到 bin\Content\Content.dll 中,当运行时搜索它时,它会自动在该子文件夹中查找。

然而 - 这不是一个好的解决方案:)

编辑 - 新解决方案

如果 Conflict.dll 的两个版本都已签名,您是否确实尝试过部署名称略有不同的版本之一?我刚刚设置了一个 winforms 应用程序,其中包含对同一(签名)程序集的不同版本的两个程序集引用。这会导致构建出现一些问题,因为最后引用的版本将部署到 bin 文件夹,而另一个则不会(因此您必须手动复制这两个版本;相应地重命名其中一个)。然后我尝试运行该应用程序,它显示一个包含两个常量字符串的消息框;程序集的每个版本都有一个。它工作得非常好。

在这里下载一个演示-不要构建它(否则你必须重命名文件);只需打开表单应用程序的 bin\debug 文件夹并运行 exe。

ClassLibrary1.dll 和 ClassLibary1vanything.dll 是程序集的 v1.0.0.0 和 v2.0.0.0,在其他方面具有相同的名称和公钥。尽管 classlibrary1vanything.dll 的文件名错误,但它仍然有效(可能是因为它已签名)。

在 app.config 中,我确实放入了代码库提示,并认为这就是它起作用的原因(最初我将其部署为不同的文件名),但后来我将其注释掉,它仍然起作用。当必须将程序集部署到子文件夹或完全不同的位置时,代码库可能最有用。

原文

我试图让MS 的这篇支持文章中提到的第二个选项起作用,但它似乎不想这样做。

毫无疑问,有一些聪明的方法可以开箱即用,但由于我还不够聪明,还没有找到它,所以我会修饰并使用上述支持主题和挂钩中显示的第三个选项进入AssemblyResolve应用程序域的事件。

如果您添加自己的配置(实际上可能只是在 appSettings 中),以便将程序集的全名绑定到不同的文件名,那么在您的 AssemblyResolve 事件处理程序中,您可以查阅要加载的程序集的名称以查看是否它在你的配置中。如果是,请抓住该位置并使用 Assembly.LoadFrom 加载它。

因此,一旦您完成了类似的操作,您只需在其中添加 Conflict v5.8 程序集名称的条目以及应用程序应使用的文件名即可。

我不知道您正在部署什么类型的应用程序,但在 win 表单中,控制台应用程序和服务AppDomain.CurrentDomain.BaseDirectory将等于 bin 文件夹,您可以使用要加载的文件名加入该文件夹。网站有点棘手。

应该好好享受一下工作。