【问题标题】:support multiple versions of third party library支持多个版本的第三方库
【发布时间】:2019-05-19 07:10:21
【问题描述】:

我创建了一个需要第三方 API 的 C# 应用程序 (MyAppV1)。我的应用程序需要使用这个 API 的多个版本,但一次只能使用一个版本。 我已经设置了我的解决方案来更改不同构建配置的引用和使用语句,并且我创建了多个可执行文件每个都针对不同的 API 版本。

目前我有这种情况:

  • MyAppV1_ThirdPartyV1.exe 使用 ThirdPartyV1.dll
  • MyAppV1_ThirdPartyV2.exe 使用 ThirdPartyV2.dll
  • MyAppV1_ThirdPartyV2_5.exe 使用 ThirdPartyV2.dll (他们没有改变 他们软件的次要版本的库名称)
  • MyAppV1_ThirdPartyV3.exe 使用 ThirdPartyV3.dll

我希望能够维护一个版本列表,可能在 App.config 中,并在运行时加载适当的 dll 库。我不知道从哪里开始。这是一个合适的策略吗?我不确定如何最好地处理这种情况。我的应用程序的多个版本唯一与引用的库不同对我来说似乎很笨重。

我找到的大部分信息都与支持多个框架、同时处理下游同一库的两个版本的需求或需要同时加载两者有关。我找不到有关如何处理我的特殊情况的信息。

【问题讨论】:

  • 您不能托管一个包含 3 个不同项目的解决方案吗?在我看来,你的努力不止加倍
  • 这个帖子应该对stackoverflow.com/questions/18362368/…有帮助
  • 第三方库的版本是否向后兼容(即,您可以使用较新的版本作为旧版本的替代品)。如果是这样,请查看配置文件中的 configuration/runtime/assemblyBinding/dependantAssembly/bindingRedirect。如果不是,我很高兴我不在你的鞋子里
  • 如果你想发布一个 exe 并且用户可以根据需要换出 dll,那么你需要使用反射动态 dll 加载。如果不是,那么只需构建 3 个版本。动态 dll 加载不是类型安全的,而且很快就会变得丑陋

标签: c# dll assemblyversions


【解决方案1】:

这在项目级别是可能的。您可以在解决方案中构建不同的配置,当您添加如下引用时,它将采用所需的 DLL

<Choose>  
  <When Condition="'$(Configuration)|$(Platform)'=='YourSpecialConfiguration1|x64'"><!-- attention here -->
    <ItemGroup>
      <Reference Include="your.dllv1.name">
        <HintPath>yourDllPath_v1\your.dllv1.dll</HintPath><!-- attention here -->
        <Private>true</Private>
      </Reference>
      <!-- more references here -->
    </ItemGroup>
  </When>
  <When Condition="'$(Configuration)|$(Platform)'=='YourSpecialConfiguration2|x64'"><!-- attention here -->
    <ItemGroup>
      <Reference Include="your.dllv2.name">
        <HintPath>yourDllPath_v2\your.dllv2.dll</HintPath><!-- attention here -->
        <Private>true</Private>
      </Reference>
      <!-- more references here -->
    </ItemGroup>
  </When>
  <Otherwise>
    <ItemGroup>
      <Reference Include="your.dllname">
        <HintPath>yourRegularPath\your.dllname.dll</HintPath><!-- attention here -->
        <Private>true</Private>
      </Reference>
      <!-- AND more references here -->
    </ItemGroup>
  </Otherwise>
</Choose> 

您在上面看到的 - 选项 1。

选项 2 - 每个版本的不同项目。缺点 - 如果添加文件或引用,则需要添加到每个项目中

选项 3 - 添加所有引用,但为每个引用声明不同的命名空间别名(在引用属性窗口中)。然后在代码中进行条件编译,如

ISomething myVar;

#if V1
    myVar = new namespace1.ClassX();
#elif V2
    myVar = new namespace2.ClassX();
#else
    . . . .
#endif

最后:

“我希望能够在 App.config 中维护一个版本列表,并在运行时加载适当的 dll 库。”

- 你可能不需要这些。您只需要生成具有不同版本的软件包。在运行时加载将需要更多的编码工作,同时仍提供所有 DLL,因为您不知道下次要加载什么。

【讨论】:

  • 嗨@T.S.我已经按照您在选项 1 中的建议进行了操作。选项 2 听起来比目前的情况需要维护更多的工作,但并没有解决我对可以根据请求加载适当 dll 的单个可执行文件的需求。我不确定我是否遵循您对选项 3 的建议“您只需要生成具有不同版本的软件包。”,这正是我目前正在做的。不过谢谢你,感谢你的详细回复。
  • @user3493725 你知道什么是绑定重定向吗?我们开始了 - 您可以针对一个版本的 dll 编译您的代码,但针对同一 dll 的不同版本运行。只需在配置文件中提供 DLL 和条目。通过修改此条目并更改 dll,您可以使用所需的任何 dll 版本。也就是说,如果签名相同。
  • 我认为这行不通。我需要用户指定(或者我的应用可以从列表中选择)。最新版本并不总是需要的版本。我的应用程序需要一个工程分析软件的运行实例,它们通常一次维护几个版本以支持旧项目。他们很少升级模型,但在开始新项目时会使用最新的软件。
  • @user3493725 除了上述技术,您还可以使用反射和调用方法加载任何程序集。您可以将程序集加载到域中,如果无法将其加载到同一域中,则可以将其加载到不同的域中。现在,我开始觉得你没有明确定义你的“成功之路”。 OP 通常会在不知道更好的方法(阅读 - 设计)的情况下要求一些东西。当您说 “我需要用户指定...”时, - 指定引用 dll 的版本?如果您已经在运行时 - 只有反射。如果在运行之前 - 您可以在哪里制作“启动应用程序”......
  • ...他们选择版本,您的启动应用程序修改绑定重定向并启动实际应用程序将其绑定到所需的 DLL 版本。
猜你喜欢
  • 1970-01-01
  • 2019-02-06
  • 1970-01-01
  • 1970-01-01
  • 2020-12-10
  • 2018-01-14
  • 2015-01-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多