首页 > 解决方案 > 在运行时将 Dll 引用切换到不同的版本

问题描述

在我的 .NET 应用程序(.NET Framework 4.8)中,我试图实现我的一个接口的实现的交换。

我有以下项目结构:

MyProgram.Exchange:

public interface IExchange {
   void DoSomething();
}

MyProgram.Exchange.V1(引用 Some.dll(版本 1.0.0.0))

[Export(typeof(IExchange))]
public class Exchange : IExchange {
   public void DoSomething(){}
}

MyProgram.Exchange.V2(引用 Some.dll(版本 2.0.0.0))

[Export(typeof(IExchange))]
public class Exchange : IExchange {
    public void DoSomething(){}
}

在我的主程序的 Startup.cs 中,我创建了一个 DirectoryCatalog 并将我的 V1 中的类型注册为默认行为:

var catalog = new DirectoryCatalog($".", $"*V1*.dll");
// ...
var builder = new Autofac.ContainerBuilder();
builder.RegisterComposablePartCatalog(catalog);

最初这工作正常。但是在我的应用程序内部的某个时刻,我需要将参考从 V1 切换到 V2。我现在的问题是,当调用“builder.RegisterComposablePartCatalog(catalog)”时出现异常,因为引用的程序集“Some.dll”已经注册到另一个版本。

有没有办法完全删除对 MyProgram.Exchange.V1 及其所有依赖项的引用并注册 MyProgram.Exchange.V2 。

对不起,如果问题的解释不是最好的,但我希望你能解决我的问题。

标签: c#autofacmef

解决方案


我认为在这种情况下,选项是使用自定义 AppDomain 动态加载程序集。

你可以像这样实现它:

  • 创建应用程序域AppDomain.CreateDomain()
  • Assembly.Load()
  • 使用实例/使用反射注册您的类型

当您需要替换 dll 时:

  • 从 DI 注册中删除类型
  • 删除 AppDomain AppDomain.Unload()(卸载已加载程序集的方式)
  • 类比地使用反射加载新的汇编和寄存器类型。

不幸的是,当您在编译时引用 dll 时,没有“卸载”它的选项。


推荐阅读