引用同一DLL的多个版本

时间:2015-09-25 14:51:39

标签: c# .net dll .net-assembly spire.doc

我有一个项目需要间接使用三个不同版本的第三方库。这些版本彼此不兼容,因此我无法使用绑定重定向 - 它必须是精确的.dll文件。 (这些库是Spire.DocSpire.XLS& Spire.PDF;所有三个都引用了Spire.PDF DLL。

我已将这三个组件分成单独的包装器项目,并创建了包含对库中任何内容的直接引用的类。但是,这并没有解决我的问题:'使用'项目仍然需要将所有库复制到bin文件夹才能运行。构建过程不知道要复制哪个版本,因此只复制最新版本。由于存在错误的DLL,这给了我运行时异常。

我考虑过/尝试过:

  • 将绑定重定向添加到特定版本(运行时异常,因为找不到库的确切版本)
  • 使用构建后步骤合并包装器项目(再次抱怨缺少库DLL的运行时异常)
  • 为应用程序的每个部分创建单独的控制台应用程序,然后单独调用它们 - 这是一个复杂的最后手段,我真的不想做!

我已经读过extern alias可能会有所帮助 - 但据我所知,你只能区分具有不同名称的程序集。 Spire.PDF库在每个项目中都具有相同的名称(以及相同的签名公共令牌)。

如何在同一解决方案中独立使用这三个独立版本的库?

修改

此问题与建议的副本略有不同,因为我无法更改依赖库中的任何代码。 Spire.Doc依赖于不同版本的Spire.PDF到Spire.XLS

1 个答案:

答案 0 :(得分:2)

在您的消费项目(项目A)中,创建一个公共接口(ISpiroPdfAlex),其中包含外部程序集的3个版本提供(并且您使用)的所有功能。您无法以任何方式从这些包装器中引用 Project A 中的任何,否则您将创建一个依赖项,这是您试图避免的。

让所有3个包装器项目导入 Project A 并实现ISpiroPdfAlex。这将使您能够通过相同的API调用3个不同版本中的每个版本。

在此之后,在 Project A 下为每个版本创建一个子文件夹(总共3个子文件夹) - 因为 Project A 没有引用任何外部程序集,它无法自行加载它们 - 当您需要正确的版本时,您必须手动加载它们。由于您的外部DLL可能具有相同名称的依赖项,因此它们不能都在同一个文件夹中(如您所写),这就是您需要子文件夹的原因。

在运行时需要其中一个版本时,可以调用Assembly.LoadFile从指定文件夹加载特定版本的程序集,然后可以使用Activator.CreateInstance或依赖注入到创建实现接口的类的实例。获得实例后,您可以自由调用任何函数,并且您将获得与版本相关的行为。

修改

OP在评论中提到,他的代码不是依赖于不同版本的PDF库,而是依赖于其代码所依赖的其他第三方Spire库。

在这种情况下,无法修改第三方代码以支持程序集的动态加载,并且它们已经具有二进制依赖性。它不可能加载不同版本的"相同"组装到同一个过程中,特别是你提到这些版本甚至不能向后兼容。

在这种情况下,我能想到的唯一解决方案是将所有依赖功能分解为单独的控制台应用程序(每个不同版本一个),并通过命令行调用这些单独的.exe-s。

要传递信息,您可以直接在命令行或stdin传递数据。或者,您可以只传递一个临时文件的名称,该文件包含进行某些处理所需的所有数据。要从控制台进程返回返回数据,您可以阅读其stdout或使用相同/不同的文件。

这样,您的主进程永远不会加载任何这些程序集并且不依赖于它们 - 每个控制台应用程序只依赖于一个版本,因此不会发生冲突。