You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

动态加载类型时Type.GetConstructor(带参数类型)调用失败问题排查

插件加载反射异常问题解析

用户问题描述

初始问题

通过AssemblyLoadContext.LoadFromAssemblyName按官方插件开发流程加载插件:

  • 插件程序集加载正常,可定位到实现指定接口的类型
  • 能通过Activator.CreateInstance实例化目标类型的无参构造函数
  • 调用Type.GetConstructor获取带特定参数(如ILogger)的构造函数时返回null,但调试确认该构造函数存在
  • 静态加载同一类型时,Type.GetConstructor调用成功

更新后问题

将ILogger参数从构造函数移至接口声明的方法后:

  • 调用Assembly.GetTypes(经RuntimeModule.GetTypes触发)抛出ReflectionTypeLoadException
  • 错误信息显示:“程序集‘blah’中类型‘blah’的方法‘blah’未实现”
  • 涉事方法正是带ILogger参数的接口方法,移除该参数后异常消失,疑似运行时无法识别主程序与插件中的ILogger为同一类型

核心原因

问题根源是**.NET AssemblyLoadContext的类型隔离机制**:

  • CLR判定类型唯一性的依据不仅是类型全名、程序集信息,还包含加载该类型的AssemblyLoadContext实例。即使是完全相同的类型,被不同上下文加载后,会被视为两个毫无关联的类型。
  • 初始问题中,主程序的ILogger类型与插件程序集引用的ILogger分属不同上下文,用主程序的ILogger类型作为参数查找构造函数时,CLR判定参数类型不匹配,因此返回null。
  • 更新后的问题里,接口定义的方法参数是主程序上下文的ILogger,但插件实现时使用的是自身上下文加载的ILogger,CLR认为插件类型未正确实现接口方法,进而抛出ReflectionTypeLoadException。

解决建议

  • 共享类型统一加载:将ILogger、插件接口等需要跨主程序与插件共享的类型,提取到独立的类库中。主程序和插件均引用该类库,且确保AssemblyLoadContext加载共享类库时,复用主程序已加载的版本(可通过LoadFromAssemblyName自动复用,或在自定义AssemblyLoadContext中重写Load方法,优先从主上下文加载共享程序集)。
  • 避免跨上下文类型传递:如果必须在主程序与插件间传递对象,可让共享类型继承MarshalByRefObject,实现跨上下文的对象访问。

内容的提问来源于stack exchange,提问作者Ian Horwill

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 02:05:29