简体   繁体   English

创建导入的MEF部件的多个实例

[英]Creating multiple instances of Imported MEF parts

Currently my WPF application imports a part like this 目前我的WPF应用程序导入了这样的部分

[Import(typeof(ILedPanel)]
public ILedPanel Panel { get; set; }

But this gives ma a single intance of the class that implements ILedPanel. 但是这给了ma实现ILedPanel的类的单个intance。 What I really want to do is have the ability to create as many instances that I need. 我真正想做的是能够创建我需要的尽可能多的实例。 Please note there is only one Export for ILedPanel included with the software at any given time. 请注意,在任何给定时间,软件中只包含一个ILedPanel导出。

(If I use an import with List that gives me one instance for every class implementing ILedPanel) (如果我使用带有List的导入,它为每个实现ILedPanel的类提供了一个实例)

Any suggestions? 有什么建议么?

I'm not sure if this is what Nicolas is referring to, but you could import a Factory class rather than an instance class, like this: 我不确定这是否是Nicolas所指的,但您可以导入Factory类而不是实例类,如下所示:

[Import(typeof(ILedPanelFactory)]
public ILedPanelFactory PanelFactory { get; set; }

...and then later in your code... ......然后在你的代码中......

ILedPanel panel = PanelFactory.BuildPanel();

All of the other answers are pretty old, so they don't mention a relatively new feature in MEF called ExportFactory . 所有其他答案都很老,所以他们没有在MEF中提到一个名为ExportFactory的相对较新的功能。 This generic class allows you to import ExportFactory<ILedPanel> and create as many instances as you like whenever you need them, so your code would look like this: 这个泛型类允许您导入ExportFactory<ILedPanel>并在需要时创建ExportFactory<ILedPanel>实例,因此您的代码将如下所示:

[Import(typeof(ILedPanel)]
public ExportFactory<ILedPanel> PanelFactory { get; set; }

public ILedPanel CreateNewLedPanelInstance()
{
    return PanelFactory.CreateExport().Value;
}

This method also satisfies any imports that created part has. 此方法还满足创建零件的任何导入。 You can read more about using the ExportFactory class here . 您可以在此处阅读有关使用ExportFactory类的更多信息。

There isn't "built in" support for this in MEF today, but before reverting to Service Locator, you might find some inspiration here: http://blogs.msdn.com/nblumhardt/archive/2008/12/27/container-managed-application-design-prelude-where-does-the-container-belong.aspx 今天在MEF中没有“内置”支持,但在恢复服务定位器之前,您可能会在这里找到一些灵感: http//blogs.msdn.com/nblumhardt/archive/2008/12/27/container -managed-应用设计前奏-其中此结果的容器-belong.aspx

The essential idea is that you 'import' the container into the component that needs to do dynamic instantiation. 基本思想是将容器“导入”需要进行动态实例化的组件。

More direct support for this scenario is something we're exploring. 我们正在探索对这种情况的更直接支持。

Nick 缺口

UPDATE: MEF now has experimental support for this. 更新: MEF现在有实验支持。 See this blog post for more information. 有关更多信息,请参阅此博客文章

Unless I misunderstand the question, it looks like it would be solved by simply using a CreationPolicy.NonShared. 除非我误解了这个问题,否则只需使用CreationPolicy.NonShared即可解决。

This assumes that the code declaring the Panel exists everywhere you want a panel. 这假定声明Panel的代码存在于您想要面板的任何位置。 You would get a new instance of ILedPanel in every instance of every class that had this declaration (the import). 您将在具有此声明(导入)的每个类的每个实例中获得ILedPanel的新实例。

Looking at the shapes game sample that comes with MEF, there is the ShapeFactory class: 看看MEF附带的形状游戏样本,有ShapeFactory类:

[Export]
public class ShapeFactory
{
    private readonly Random random = new Random((int)DateTime.Now.Ticks);

    [Import]
    private ICompositionService CompositionService { get; set; }

    public IShape GetRandomShape()
    {
        var shapeRetriever = new ShapeRetriever();

        CompositionService.SatisfyImports(shapeRetriever);

        int randomIndex = random.Next(shapeRetriever.PossibleShapes.Length);

        return shapeRetriever.PossibleShapes[randomIndex].GetExportedObject();
    }

    private class ShapeRetriever
    {
        [ImportMany(RequiredCreationPolicy = CreationPolicy.NonShared)]
        public Export<IShape, IShapeMetadata>[] PossibleShapes { get; set; }
    }
}

Which demonstrates creating a random shape instances "on demand"... I would think in your scenario you could do something similar without the selection of a random implementation, as you suggest there would be only one implementation of ILedPanel registered. 这演示了如何“按需”创建随机形状实例......我认为在您的场景中,您可以在不选择随机实现的情况下执行类似操作,因为您建议只有一个ILedPanel注册实现。

i think you mean you want to use MEF in this instance like a service locator rather than a dependency injection container. 我认为你的意思是你想在这个实例中使用MEF,就像服务定位器而不是依赖注入容器一样。 Try looking at examples for ValueResolver 尝试查看ValueResolver的示例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM