如何将现有实例添加到 MEF 目录?

发布于 2024-10-31 12:00:48 字数 1732 浏览 0 评论 0原文

我有一个对象实例,我希望最终得到一个包含该对象实例并导出为特定接口类型的 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,并且能够将它们全部拔出稍后再用其他东西替换它们?

I have an object instance, and I want to end up with a MEF catalog that contains that object instance, exported as a specific interface type. How can I do this?

TypeCatalog doesn't seem workable here, because (a) it creates a new instance instead of using an existing one, and (b) it requires the type to have an [Export] attribute. In my case, the instance comes from MEF's metadata system, so MEF creates the underlying type and I can't add attributes to it.

As far as I can tell, the usual advice is, if you've got an existing instance, you should add it to the container (e.g. via CompositionBatch), not to the catalog. But when I add this instance, I'm also adding an entire AssemblyCatalog worth of types, all in the same operation. I'll also want to be able to remove all of these types later. It makes more sense to me to bundle everything into an AggregateCatalog. That way, I can add both the assembly and the instance in one atomic operation, and I can remove them all again the same way.

For example:

// 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);
}

The part I don't know how to do is "MakeCatalogFromInstance". How can I create a catalog that contains an existing instance (registered as a specific type)?

Or, alternatively, if I'm going about this all wrong, is there a better way to plug an entire catalog and an existing instance all into MEF at the same time, with the ability to unplug them all again later and replace them with something else?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

等数载,海棠开 2024-11-07 12:00:48

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

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

I think it's probably best to add the types to the catalog and then add the instance to the container.

Catalogs contain part definitions. Part definitions are used to create parts. (The types for this are ComposablePartDefinition and ComposablePart.) So you could theoretically write your own catalog and a part definition that always returned a part corresponding to the instance when CreatePart was called. But catalogs weren't really designed to be used this way.

隔岸观火 2024-11-07 12:00:48

为了繁荣......

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

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

希望有帮助,
马克

For prosperity...

MEF devivides the chores of what type info is to be used (catalog) from the actual running object instances (container). To me it is a logical descicion, especially when you setup a more complex MEF environment in your application.

If you want the ability to 'change' containers on the fly, I would suggest you try to use hierarchical containers. The root catalog/container is filled with static types and any of the child containers can be filled with each specific set of meta types you need for your game.

Hope it helps,
Marc

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文