我正在玩MEF,在示例中我看到了这段代码(我称之为MEF撰写代码):
var catalog = new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly());
var container = new CompositionContainer(catalog);
container.ComposeParts();
在大多数示例中,这是在与Startup Program类相同的源文件中完成的,以及所有其他接口和类。
现在我想使用MEF,但我想知道这个容器做了什么。据我所知它导出导出/导入映射,但如果我有这个代码(来自Windows窗体应用程序:
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
并且在那个Form1中我想创建一个Auditer类型的对象(它具有ILogger类型的属性标记为import,并且我有一个实现ILogger标记导出的类。)
我是否必须将MEF编写代码放在void Main(),Form1的Load事件或Auditer类的构造函数中?
当我把它(MEF编写代码)放在Auditer类的构造函数中时,我才能使它工作,但我读到的例子给了我一个想法,你只需要调用一次compose代码。
答案 0 :(得分:2)
CompositionContainer
是实际在MEF中组成部件的类。
如果要使用MEF,则需要始终组成使用导入定义归属的部分。如果您在Form1
中有一个标有[Import(typeof(ILogger))]
的媒体资源,则在某些时候,您需要撰写您的Form1实例。
CompositionContainer
是实际执行此合成的类。它根据容器中包含的目录找到适当的导出ILogger
,并构造类型,匹配导入到导入等。
MEF样本仅“组合”一次的原因是,通常使用DI,您将在应用程序的开头构建和设置容器的单个实例,它将组成您的“主要” “窗口。如果它们被用作主窗口的一部分,则所有其他类将自动组合。 (例如,如果Form1组成了一个ILogger,但是你的ILogger实现有一个[Import]
,它也会在那个传递中组合。)
话虽如此,没有固定的规则规定你不能多次撰写。例如,在WPF和Silverlight中,MEF 不能构建对象的频率很高,这意味着它无法自动为您构建对象。在这些情况下,常见的模式是使用CompositionInitializer(在Silverlight中的框中,而不是在桌面中)使部件基于静态目录自行组成。 I recently blogged about this approach for WPF
使用Windows窗体,这可能不太必要,因为没有第三方产品(XAML解析器)构建您的类型。但是,如果您愿意,仍然可以使用相同的方法。