托管可扩展性框架(MEF)基础知识






3.24/5 (6投票s)
本文通过一个简单的示例为初学者解释了 MEF 的基础知识
引言
Managed Extensibility Framework (MEF),或称 MEF,是一个用于创建轻量级、可扩展应用程序的库。 它是 .NET 的组合层,可以提高大型应用程序的灵活性、可维护性和可测试性;它是一种松耦合的插件架构,可以轻松封装代码。
MEF 是 .NET Framework 4 的一个组成部分,并且可以在使用 .NET Framework 的任何地方使用。 您可以在客户端应用程序(无论它们是使用 Windows Forms、WPF 还是任何其他技术)或使用 ASP.NET 的服务器应用程序中使用 MEF。
关键概念
- 导出
- Export 特性装饰器会将类引入容器,任何声明了匹配契约的 export 都会从容器中满足此 import。
- 导入
- Import 特性装饰器将从容器中提取类。 每个 import 都有一个契约,它决定将匹配哪些 exports。
- 契约
- 契约可以是显式指定的字符串,也可以由 MEF 从给定的类型自动生成。
- 零件
- 所有 import 和 exportable 组件通常被称为 Parts(部件)。
- 组成
- MEF 组合模型的核心是组合容器,它包含所有可用的部件并执行组合。 CompositionContainer 使用 Catalog 发现部件。 Catalog 是一个对象,它使从某些来源发现的部件可用。 MEF 提供了 Catalog 以从提供的类型、程序集或目录中发现部件。
- 根据发现方式,Catalog 可被分类为:
- TypeCatalog - 从类型集合中发现带有特性的部件。
- AssemblyCatalog - 发现托管代码程序集中的带有特性的部件。
- DirectoryCatalog - 发现指定目录中的程序集内的带有特性的部件。
- AggregateCatalog - 一个聚合 Catalog,它组合了多个 Catalog。
- System.ComponentModel.Composition
- 这个 .Net Framework 参考提供了上述 MEF 实现类。
描述
这些代码示例解释了一个非常简单的 MEF 实现,此演示应用程序将在控制台输出和窗口消息框输出中显示消息。
MEFDemo 解决方案有四个项目:
- MEFDemo - 此项目使用 CompositionContainer 发现可导出的部件并调用 ShowMyMessage 方法。
- MEFDemo.Interfaces - 此项目具有简单的接口 IMyMessage,其中包含方法声明 ShowMyMessage。
- MEFDemo.ConsoleMessage - 此项目具有 IMyMessage 的控制台输出实现。
- MEFDemo.WindowsMessage - 此项目具有 IMyMessage 的 Windows 消息框输出实现。
在此示例中,DirectoryCatalog 用于从目录 DLL(应用程序根路径中的文件夹)发现可导出的部件,通过以下代码。
catalog.Catalogs.Add(new DirectoryCatalog(
(new DirectoryInfo(
Path.Combine(Directory.GetCurrentDirectory(), "../../../DLLs"))
).FullName
));
TypeCatalog 和 AssemblyCatalog 可用于发现可导出的部件。
以下代码从容器中提取实现了 IMyMessage 契约的类。
var myMessages = _container.GetExportedValues<IMyMessage>();
IMyMessage
IMyMessage 接口具有 ShowMessage 的方法声明,请参见以下代码。
public interface IMyMessage
{
void ShowMyMessage(string message);
}
此接口在控制台和 Windows 消息显示中实现。
控制台和 Windows 实现
IMyMessage 接口实现控制台和 Windows 消息,用于显示不同的消息输出格式。
//This class can be export to CompositionContainer - If decorated with Export attribut
// with IMyMessage as contract, then this class can be export to composition container
// and then this can be import whenever it necessary from the container
[Export(typeof(IMyMessage))]
public class MyMessage : IMyMessage
{
public void ShowMyMessage(string message)
{
Console.WriteLine("Hi I am from {0}, {1}", "Console", message);
}
}
Windows 消息框显示的实现相同,请参见以下代码。
[Export(typeof(IMyMessage))]
public class MyMessage : IMyMessage
{
public void ShowMyMessage(string message)
{
MessageBox.Show(string.Format("Hi I am from {0}, {1}", "Window", message));
}
}
ConsoleMessage 和 WindowsMessage 是单独的项目,并且与 MEFDemo 应用程序没有直接交互。
输出
通过从以下文件夹中删除任何一个 DLL,相应的消息将不会出现在输出中。
结论
我希望本文能帮助您了解 MEF 实现的一些基础知识,并欢迎您撰写您对此文章的评论和问题。
参考
1. http://msdn.microsoft.com/en-us/library/dd460648(v=vs.110).aspx