我有一个对象实例,我希望最终得到一个包含该对象实例的MEF目录,并作为特定的接口类型导出。我怎么能这样做?
TypeCatalog在这里似乎不可行,因为(a)它创建一个新实例而不是使用现有实例,(b)它要求类型具有[Export]属性。在我的例子中,实例来自MEF的元数据系统,因此MEF创建了底层类型,我无法为其添加属性。
据我所知,通常的建议是,如果你有一个现有的实例,你应该把它添加到容器(例如通过CompositionBatch),而不是目录。但是当我添加这个实例时,我还要添加一个完整的AssemblyCatalog类型,所有这些都在同一个操作中。我还希望以后能够删除所有这些类型。将所有内容捆绑到AggregateCatalog中对我来说更有意义。这样,我可以在一个原子操作中添加程序集和实例,我可以用同样的方法再次删除它们。
例如:
// 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);
}
我不知道该怎么做的部分是“MakeCatalogFromInstance”。如何创建包含现有实例的目录(注册为特定类型)?
或者,或者,如果我说这一切都错了,是否有更好的方法将整个目录和同时插入到MEF中,并且能够之后再将它们全部拔掉并用其他东西替换它们?
答案 0 :(得分:1)
我认为最好将类型添加到目录中,然后将实例添加到容器中。
目录包含零件定义。零件定义用于创建零件。 (其类型为ComposablePartDefinition
和ComposablePart
。)因此,理论上您可以编写自己的目录和部件定义,在调用CreatePart
时始终返回与实例对应的部件。但目录并没有真正用于这种方式。
答案 1 :(得分:1)
为了繁荣......
MEF从实际运行的对象实例(容器)中分离了要使用的类型信息(目录)的杂事。对我而言,这是一个逻辑上的说法,特别是当您在应用程序中设置更复杂的MEF环境时。
如果您希望能够动态“更改”容器,我建议您尝试使用分层容器。根目录/容器中填充了静态类型,任何子容器都可以填充游戏所需的每个特定元类型集。
希望它有所帮助, 马克