MEF移除部件时抛出InvalidOperationException异常原因咨询
问题原因分析
核心矛盾在于循环引用的可重组部件 + 非共享(NonShared)创建策略 + 动态移除部件的组合触发了MEF内部的资源管理冲突,具体执行流程和异常触发逻辑如下:
执行流程拆解
添加Module到容器阶段
- 手动创建
mod1并通过CompositionBatch加入容器后,MEF发现Module的Admin导入需要满足。由于Admin标记为NonShared创建策略,容器会生成一个新的Admin实例(记为Admin1)。 - 双向引用建立:
mod1.Admin被赋值为Admin1,同时Admin1.Module被赋值为mod1,两者均触发属性setter和OnImportsSatisfied方法。
- 手动创建
移除Module时的异常触发逻辑
- 调用
RemovePart移除mod1时,MEF启动依赖清理流程:- 由于
Admin1是容器创建的NonShared部件,且它唯一的依赖(Module实例mod1)被移除,MEF会自动释放Admin1(调用其Dispose方法)。 - 但因为
Admin的Module导入标记了AllowRecomposition = true,MEF会尝试对Admin1执行重组操作——试图将其Module属性设为null(原导出已被移除)。 - 此时
Admin1对应的ComposablePart已经被释放,MEF内部尝试访问该已释放部件时,直接抛出ObjectDisposedException,最终封装为外层的AggregateException和InvalidOperationException。
- 由于
- 调用
为什么设为Shared能解决问题?
当Admin的创建策略改为Shared时,容器只会生成一个Admin实例,且该实例的生命周期由容器直接管理,不会因依赖的Module被移除而自动释放。因此移除mod1时,Admin实例仍处于存活状态,MEF可以正常执行重组操作,不会访问已释放的对象。
补充说明
MEF的重组机制与非共享部件的自动释放逻辑在循环引用场景下存在设计冲突:当两个可重组部件互相引用且其中一个为非共享类型时,移除手动添加的部件会触发非共享部件的释放,但重组流程仍会尝试操作已释放的部件,最终导致异常。
内容的提问来源于stack exchange,提问作者user26344415
相关产品推荐
相关产品推荐

