4

我有一个对象实例,我想最终得到一个包含该对象实例的 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,并且能够稍后再次拔出它们并用某些东西替换它们别的?

4

2 回答 2

1

我认为最好将类型添加到目录中,然后将实例添加到容器中。

目录包含零件定义。零件定义用于创建零件。(此类型为ComposablePartDefinitionComposablePart。)因此,理论上您可以编写自己的目录和部件定义,在CreatePart调用时始终返回与实例对应的部件。但是目录并不是真正设计成以这种方式使用的。

于 2011-04-11T04:59:23.390 回答
1

为了繁荣...

MEF 将要使用的类型信息(目录)从实际运行的对象实例(容器)中分离出来。对我来说,这是一个合乎逻辑的决定,尤其是当您在应用程序中设置更复杂的 MEF 环境时。

如果您想要动态“更改”容器的能力,我建议您尝试使用分层容器。根目录/容器填充静态类型,任何子容器都可以填充游戏所需的每组特定元类型。

希望它有帮助,马克

于 2012-11-15T19:04:54.323 回答