c# - 在运行时将 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 。
对不起,如果问题的解释不是最好的,但我希望你能解决我的问题。
解决方案
我认为在这种情况下,选项是使用自定义 AppDomain 动态加载程序集。
你可以像这样实现它:
- 创建应用程序域
AppDomain.CreateDomain()
Assembly.Load()
- 使用实例/使用反射注册您的类型
当您需要替换 dll 时:
- 从 DI 注册中删除类型
- 删除 AppDomain
AppDomain.Unload()
(卸载已加载程序集的方式) - 类比地使用反射加载新的汇编和寄存器类型。
不幸的是,当您在编译时引用 dll 时,没有“卸载”它的选项。
推荐阅读
- xamarin.android - 尝试将 admob 添加到项目时出错
- c++ - 将声明的枚举转发为类成员变量
- javascript - 为 React Native Web 项目使用适当的转译器
- python - KivyLauncher:手机屏幕上的错误图像
- sql - 如何从单个列上带有附加 where 子句的表中进行选择
- .net - 由于 system.net.http 缺少参考的问题,无法使用 Microsoft Graph 3.2.0 运行 C# 应用程序
- sonarqube - 分析成功后如何在单独的调用中将 JaCoCo 报告上传到 SonarQube?
- makefile - CalculiX 安装错误 etime (在函数 `second_':)
- css - 是否可以在 CSS 中设置子字符串的样式?
- python - 如何在 Flask admin 中的 GUI/请求中更改输入数据,然后再转换为表单?如果编辑/创建模型