c# - AssemblyLoadContext,动态加载程序集,实例化对象并强制转换为共享接口
问题描述
我正在尝试使用AssemblyLoadContext
(从 netcore 3.0 版中存在)加载程序集,实例化一个对象并将此对象转换为接口,但出现转换异常错误。
该接口在加载程序集的项目和实例化的实现之间共享。该对象显然已正确实例化,但是当我这样做时出现意外错误(T)instance
。
尝试使用观察者,我能够按照我正在使用的代码和观察者的屏幕截图将实例正确地投射到界面:
private (ExecutionAssemblyLoadContext, T) LoadTheAssemblyAndInstance<T>(string assemblyName, string typeNameToInstance)
{
var basePath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
var assemblyContext = new ExecutionAssemblyLoadContext($"{basePath}/{assemblyName}.dll");
var assembly = assemblyContext.LoadFromAssemblyPath($"{basePath}/{assemblyName}.dll");
var externalCodeEvent = typeNameToInstance != null ? assembly.ExportedTypes
.Where(x => x.FullName == typeNameToInstance)
.Single() : assembly.ExportedTypes.First();
var instance = Activator.CreateInstance(
externalCodeEvent,
_defaultConstructorParameters
);
return (assemblyContext, (T)instance);
}
这是完整的异常消息:
System.InvalidCastException:'无法将'Expriva.NewWorkflow.BPMN.ExecutionCodeTest.ExecutionContractTest'类型的对象转换为'Expriva.NewWorkflow.ExternalShared.Interfaces.IExecutionContract'。
解决方案
AssemblyLoadContext 支持动态代码加载和卸载,它在自己的 AssemblyLoadContext 实例中创建用于加载代码及其依赖项的隔离上下文。
问题是在 ExecutionAssemblyLoadContext 实现中,依赖关系被解决和隔离。使用默认实现,AssemblyLoadContext 的文档表明共享类型不会被隔离。按照正确的实现来使用共享接口。
public class ExecutionAssemblyLoadContext : AssemblyLoadContext
{
public ExecutionAssemblyLoadContext() : base(isCollectible: true)
{
}
protected override Assembly Load(AssemblyName name)
{
return null;
}
}
推荐阅读
- microsoft-graph-api - 通过 Microsoft Graph Explorer 提取 Microsoft Teams 用户活动数据
- c++ - 编译错误:int main 中有多个定义
- gatsby - Gatsby Strapi 不加载样式
- c++ - Gstreamer rtsp-server 控制方式
- flutter - Flutter:从 Dart 隔离打印到控制台?
- vega-lite - 在由任意离散轴上的离散和连续数据组成的多视图布局中绘制数据
- spring-cloud-contract - Spring Cloud Contract Stub Runner 支持哪些编程语言?
- r - Ggplot,Last Geom_point 着色覆盖第一个着色
- sql-server - 是否可以将 SSRS 报告中的图表导出为 PDF?
- terraform - 有什么方法可以使用名称设置 Terraform 资源属性?