2

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

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

我考虑过/尝试过的:

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

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

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

编辑:

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

4

1 回答 1

2

在您的使用项目(项目 A)中,创建一个通用接口 ( ISpiroPdfAlex),其中包含 3 个版本的外部程序集提供(以及您使用)的所有功能。您不能以任何方式从这些包装器中引用项目A中的任何内容,否则您将创建一个依赖项,这是您要避免的。

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

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

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

编辑

OP 在评论中提到,依赖于不同版本的 PDF 库的不是他的代码,而是他的代码所依赖的其他 3rd-party Spire 库。

在这种情况下,无法修改第 3 方代码以支持程序集的动态加载,并且它们已经具有二进制依赖项。不可能将“相同”程序集的不同版本加载到同一进程中,尤其是您提到这些版本甚至不相互向后兼容。

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

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

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

于 2015-09-25T15:08:58.670 回答