【问题标题】:How can I add an existing instance to a MEF catalog?如何将现有实例添加到 MEF 目录?
【发布时间】:2011-04-11 01:08:58
【问题描述】:

我有一个对象实例,我想最终得到一个包含该对象实例的 MEF 目录,并导出为特定的接口类型。我该怎么做?

TypeCatalog 在这里似乎不可行,因为 (a) 它创建一个新实例而不是使用现有实例,并且 (b) 它要求类型具有 [Export] 属性。在我的例子中,实例来自 MEF 的元数据系统,所以 MEF 创建了底层类型,我不能向它添加属性。

据我所知,通常的建议是,如果你有一个现有的实例,你应该将它添加到 container(例如通过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,并且能够稍后再将它们全部拔掉并用其他东西替换它们?

【问题讨论】:

标签: mef catalog


【解决方案1】:

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

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

【讨论】:

  • 我觉得非常奇怪的是,MEF 将声明“这里是获得 X 的地方”的责任分配给两个完全不同的类。如果您打算以一种方式使用它(惰性初始化),则必须使用 Catalog;如果您打算以其他方式使用它(现有实例),则必须使用 Container。为什么它有这样一个泄漏的抽象?
【解决方案2】:

为了繁荣......

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

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

希望对你有帮助, 马克

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多