我有一个对象实例,我想以包含该对象实例的MEF编目结束,并导出为特定的接口类型。我该怎么做呢?
TypeCatalog在这里似乎不可行,因为(a)它创建了一个新实例,而不是使用现有的实例,(b)它要求类型具有[Export]属性。在我的例子中,实例来自MEF的元数据系统,所以MEF创建底层类型,我不能给它添加属性。
据我所知,通常的建议是,如果你有一个现有的实例,你应该把它添加到容器(例如,通过compostionbatch),而不是到目录。但是当我添加这个实例时,我也添加了一个完整的AssemblyCatalog类型,所有这些都在同一个操作中。我还希望以后能够删除所有这些类型。对我来说,将所有内容捆绑到aggregatecalog中更有意义。这样,我就可以在一个原子操作中添加程序集和实例,并可以以同样的方式再次删除它们。
例如:// Bootstrapper code to initialize MEF:
public void Configure() {
_selectedGameCatalog = new AggregateCatalog();
var globalCatalog = new AggregateCatalog(_selectedGameCatalog);
_container = new CompositionContainer(globalCatalog);
// ... more MEF initialization ...
}
// Sometime later, I want to add more stuff to the MEF ecosystem:
public void SelectGame(Lazy<Game, IGameMetadata> entry) {
var newCatalog = new AggregateCatalog();
// Make the assembly available to import:
newCatalog.Catalogs.Add(new AssemblyCatalog(entry.Value.GetType().Assembly));
// I also want the metadata to be available to import:
IGameMetadata metadata = entry.Metadata;
newCatalog.Catalogs.Add(MakeCatalogFromInstance<IGameMetadata>(metadata));
// Replace whatever game was selected before:
_selectedGameCatalog.Catalogs.Clear();
_selectedGameCatalog.Catalogs.Add(newCatalog);
}
我不知道如何做的部分是"makecatalogfroinstance"。如何创建包含现有实例(注册为特定类型)的编目?
或者,如果我做错了,是否有更好的方法可以同时将整个目录和现有实例全部插入MEF,并能够稍后将它们全部拔掉并用其他东西替换它们?我认为最好先将类型添加到目录中,然后将实例添加到容器中。
目录包含部件定义。部件定义用于创建部件。(此类型为ComposablePartDefinition
和ComposablePart
。)因此,理论上您可以编写自己的目录和部件定义,当CreatePart
被调用时,它总是返回与实例对应的部件。但是目录并不是这样设计的
为了繁荣…
MEF将要使用的类型信息(目录)与实际运行的对象实例(容器)区分开来。对我来说,这是一个合乎逻辑的决定,特别是当您在应用程序中设置更复杂的MEF环境时。
如果您希望能够动态地"更改"容器,我建议您尝试使用分层容器。根目录/容器由静态类型填充,任何子容器都可以由游戏所需的特定元类型填充。
希望有帮助,Marc