c# - netcore 3.1 中的 AssemblyLoadContext.Default 解析插件类型,但当插件使用传递依赖时无法执行其实例
问题描述
我在 netcoreapp3.1 中有一个使用 netstandard2.0 插件的控制台应用程序。该插件引用一个类库并实现一个接口所有dll依赖项都在插件文件夹中,plugin.dep.json包含所有引用的库。
当我运行时:
AssemblyLoadContext.Default.LoadFromAssemblyPath("path/to/main_myplugin.dll");//load plugin
它解析接口的类型
当我尝试运行下面给出的实例时,它失败了:
if (type != null) //type is resolved and not null
{
var instance = (IContract)Activator.CreateInstance(type); //instance is created
Console.WriteLine($"Create instance : {instance.GetType()}"); // ok instance is created
var ret = instance.Execute(); //!!!fire exception here
Console.WriteLine(ret);
}
并触发错误消息:
System.IO.FileNotFoundException:'无法加载文件或程序集'MyLibObjectsLib,版本 = 1.0.0.0,文化 = 中性,PublicKeyToken = null'。该系统找不到指定的文件。'
如果我加载了所有依赖项,它工作正常。
使用 AssemblyLoadContext.Default 时应该加载所有依赖项还是一个错误?
解决方案
我在dotnet项目中问过这个问题
所有功劳归@vitek-karas。
详细的答案是:
目前这是设计使然。LoadFromAssemblyPath 以及任何其他类似 LoadAssembly 的方法只会加载该程序集,它们不会尝试加载“插件”。对于这种情况,您需要 AssemblyDependencyResolver 并将其连接到默认 ALC(可能通过 Resolving 事件),并希望主机应用程序和插件之间没有冲突(因为它们将共享所有依赖项)等等上。通常这就是为什么最好将插件加载到他们自己的 ALC 中,因为这会创建必要的隔离,并且还可以轻松连接 AssemblyDependencyResolver。
更高级别的答案 - 在 3.0 中,我们没有尝试提供“插件加载”API,因为在它应该如何表现方面存在太多悬而未决的问题(确切的隔离行为很难正确处理,因此它适用于大多数人用例)。相反,我们提供了必要的构建块(ALC、ADR、diag 改进......)并依靠用户编写 cca 20 行代码来实现自定义 ALC。在 5.0 中,我们通过在整个程序集绑定过程中添加详细跟踪来改进诊断,这通常有助于在加载程序集时调试问题,特别是在实现自定义 ALC 时。
推荐阅读
- r - “命名空间 'vctrs' 0.3.6 已加载,但 >= 0.3.8 是必需的”重新安装 vctrs 后错误仍然存在
- android - 什么android studio编辑器功能依赖于自定义视图和declare-styleable应该匹配的约定?
- python - 如何从 html 脚本标签中获取数据到我的 python 函数中?
- javascript - 如何以角度8将svg文本渲染到dom元素
- flutter - 如何对齐更多的滑块?
- botframework - 如何在基于 MS 团队搜索的消息扩展应用程序包中添加屏幕截图?
- process - 处理表格多维数据集并获取包含所有消息的旧窗口
- python - Python eyed3 和获取 Musicbrainz 的标签
- vue.js - vue-svg-loader 出现问题 - 缺少模板或渲染功能
- python - 如何使交易号有序号?