讲师中心 微信公众号
AI工具推荐 视频效率加速

C# MEF组合框架方法 C#如何使用Managed Extensibility Framework实现插件化

小明大大_2410

小明大大_2410

发布时间:2026-02-24 10:26:03

|

536人浏览过

|

来源于php中文网

原创

MEF 的 CompositionContainer 负责执行组合,ComposablePartCatalog 负责声明可导入/导出的类型;必须先配置 catalog,否则 ComposeParts 会静默失败或抛 ChangeRejectedException。

c# mef组合框架方法 c#如何使用managed extensibility framework实现插件化

什么是 MEF 的 CompositionContainer 和 ComposablePartCatalog

MEF 的核心是把类型发现、依赖解析、实例创建这三件事拆开:用 ComposablePartCatalog 告诉框架“哪些类型可被导入/导出”,再用 CompositionContainer 执行实际的组合。不先配置好 catalog,CompositionContainer 就像没装弹药的枪——调用 ComposeParts 会静默失败或抛 ChangeRejectedException。

常用 catalog 类型有:AssemblyCatalog(从指定程序集扫描)、DirectoryCatalog(扫描目录下所有 DLL)、AggregateCatalog(合并多个 catalog)。注意 DirectoryCatalog 不会递归子目录,且只加载能成功 Assembly.LoadFrom 的文件;若插件 DLL 依赖未部署的第三方库,它会被跳过,也不会报错——这是最常被忽略的“静默丢失插件”原因。

  • 调试时可遍历 catalog.Parts 确认导出类型是否被识别
  • 避免在 DirectoryCatalog 路径中混入 PDB 或 XML 文档文件,它们可能触发 BadImageFormatException
  • 使用 AggregateCatalog 时,后添加的 catalog 优先级更高(同名 contract 会被覆盖)

[Import] 和 [Export] 必须成对出现且 contract 匹配

MEF 不靠类型名匹配,而是靠 contract name。默认 contract name 是导出类型的全名(如 "MyPlugin.ICommand"),但一旦你给 [Export] 指定了字符串参数,比如 [Export("IHandler")],那 [Import] 就必须写成 [Import("IHandler")],否则组合失败。更隐蔽的问题是:如果导出类实现了多个接口,又没显式指定 contract,MEF 会为每个接口生成一个导出,但 [Import] 若只写接口类型,可能意外绑定到非预期的那个。

建议统一用命名 contract + 接口类型约束:

[Export(typeof(ICommand), "FileSaveCommand")]
public class SaveCommand : ICommand { ... }

[Import("FileSaveCommand")]
public ICommand SaveCommand { get; set; }
  • [Import] 属性字段不能是 private,必须是 public 或 internal(且类本身需标记 [PartCreationPolicy(CreationPolicy.NonShared)] 才支持 private set)
  • 不要在构造函数里直接 new 导入对象——MEF 还没开始组合,此时字段为 null
  • 若需要延迟加载,用 [ImportLazy] 配合 Lazy<T>,避免提前实例化代价高的插件

如何安全释放插件并处理 CompositionException

MEF 默认不管理插件生命周期,CompositionContainer 本身也不实现 IDisposable,但如果你用了 DirectoryCatalog 并希望热替换插件,就必须手动清理:先调用 container.ReleaseExport(仅对 ExportLifetimeContext<T> 有效),再重建 container 和 catalog。更现实的做法是——别热更新,重启进程。

C#
C#

"避开 C# 常见错误——空陷阱、异步陷阱、LINQ 陷阱及资源泄漏。"

下载

组合失败时抛出的 CompositionException 错误信息非常简陋,只说“无法满足导入”,真正原因藏在 Exception.Errors 里。必须遍历这个集合才能看到具体哪条导入失败、缺哪个导出、冲突在哪。

  • 永远用 try/catch (CompositionException ex) 包裹 container.ComposeParts(this)
  • 检查 ex.Errors.Select(e => e.Element.DisplayName) 定位到具体属性或构造函数参数
  • 若插件抛异常导致构造失败,MEF 会包装成 CompositionContractMismatchException,根源还是插件自身逻辑问题

.NET Core/.NET 5+ 中为什么 System.ComponentModel.Composition 不推荐用了

原生 MEF(即 System.ComponentModel.Composition)在 .NET Core 一开始就未被移植,官方只提供了兼容层(Microsoft.Composition),但它不支持 DirectoryCatalog、没有异步组合、且已停止维护。现在标准做法是用 Microsoft.Extensions.DependencyInjection 配合手动扫描程序集,或改用 MEF2(System.Composition 命名空间),后者是轻量重写版,支持 .NET Standard 2.0+,但语法略有差异:比如 [Export] 不再接受字符串 contract name,必须用泛型 [Export<ICommand>],且 CompositionHost 替代了 CompositionContainer。

如果你正在新项目中考虑插件化,直接跳过传统 MEF——用 AssemblyLoadContext 加反射扫描 + DI 容器注册,控制力更强,调试路径更直。

MEF 的抽象层级其实很高,一旦组合行为不符合预期,排查链路远比手动 new 对象加字典映射来得晦涩。特别是跨版本、混合使用不同 MEF 实现时,contract 解析规则的微小差异就足以让插件彻底失联。

热门AI工具

更多
UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

549

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

1678

2024.03.01

pdf怎么转换成xml格式
pdf怎么转换成xml格式

将 pdf 转换为 xml 的方法:1. 使用在线转换器;2. 使用桌面软件(如 adobe acrobat、itext);3. 使用命令行工具(如 pdftoxml)。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

4584

2024.04.01

xml怎么变成word
xml怎么变成word

步骤:1. 导入 xml 文件;2. 选择 xml 结构;3. 映射 xml 元素到 word 元素;4. 生成 word 文档。提示:确保 xml 文件结构良好,并预览 word 文档以验证转换是否成功。想了解更多xml的相关内容,可以阅读本专题下面的文章。

5957

2024.08.01

xml是什么格式的文件
xml是什么格式的文件

xml是一种纯文本格式的文件。xml指的是可扩展标记语言,标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。想了解更多相关的内容,可阅读本专题下面的相关文章。

2462

2024.11.28

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

1758

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2724

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

6084

2023.10.24

Playwright 测试失败怎么办
Playwright 测试失败怎么办

Playwright测试失败专题汇集超时、定位器匹配、浏览器提前关闭、依赖与插件配置、文件上传、SSL及Docker启动等故障文章,并介绍通过截图、报告和Trace定位错误。

0

2026.10.21

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn