在C#中,Managed Extensibility Framework (MEF) 是一个轻量级的扩展性框架,它允许开发者以解耦的方式创建可扩展的应用程序。[ImportMany] 是 MEF 提供的一个特性,用于导入多个满足特定契约(contract)的组件。
当使用 [ImportMany] 时,MEF 会查找所有与指定契约匹配的导出(export),并将它们注入到一个集合中。这允许你导入多个组件,而不仅仅是单个组件。
下面是一个简单的示例来说明如何使用 [ImportMany]:
首先,定义一个契约接口:
public interface IPlugin
{
void Execute();
}
然后,创建几个实现该接口的类:
[Export(typeof(IPlugin))]
public class PluginA : IPlugin
{
public void Execute()
{
Console.WriteLine("Plugin A is executing.");
}
}
[Export(typeof(IPlugin))]
public class PluginB : IPlugin
{
public void Execute()
{
Console.WriteLine("Plugin B is executing.");
}
}
注意每个类上的 [Export(typeof(IPlugin))] 特性,它告诉 MEF 这些类可以作为 IPlugin 契约的导出。
接下来,在另一个类中,使用 [ImportMany] 来导入所有 IPlugin 的实现:
public class Host
{
// 导入所有IPlugin的实现
[ImportMany]
public IEnumerable<IPlugin> Plugins { get; set; }
public void ExecuteAllPlugins()
{
foreach (var plugin in Plugins)
{
plugin.Execute();
}
}
}
最后,你需要设置 MEF 的组合容器(CompositionContainer)来解析依赖关系并填充 [ImportMany] 属性:
var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var container = new CompositionContainer(catalog);
var host = new Host();
container.ComposeParts(host);
host.ExecuteAllPlugins(); // 这将输出两个插件的执行信息
在上面的代码中,AssemblyCatalog 用于指定包含导出类的程序集。然后,创建一个 CompositionContainer 并使用它来解析 Host 类中的导入。调用 ComposeParts 方法后,host.Plugins 集合将被填充所有实现了 IPlugin 接口的类实例。最后,通过调用 ExecuteAllPlugins 方法,可以执行所有插件。
这就是 [ImportMany] 在 MEF 中的基本用法。它允许你以一种灵活且解耦的方式构建可扩展的应用程序。