Creating multiple instances of Imported MEF parts

流过昼夜 提交于 2019-12-04 17:58:03

问题


Currently my WPF application imports a part like this

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

But this gives ma a single intance of the class that implements ILedPanel. 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.

(If I use an import with List that gives me one instance for every class implementing ILedPanel)

Any suggestions?


回答1:


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

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. See this blog post for more information.




回答2:


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:

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

...and then later in your code...

ILedPanel panel = PanelFactory.BuildPanel();



回答3:


All of the other answers are pretty old, so they don't mention a relatively new feature in MEF called 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:

[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.




回答4:


Unless I misunderstand the question, it looks like it would be solved by simply using a CreationPolicy.NonShared.

This assumes that the code declaring the Panel exists everywhere you want a panel. You would get a new instance of ILedPanel in every instance of every class that had this declaration (the import).




回答5:


Looking at the shapes game sample that comes with MEF, there is the ShapeFactory class:

[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.




回答6:


i think you mean you want to use MEF in this instance like a service locator rather than a dependency injection container. Try looking at examples for ValueResolver



来源:https://stackoverflow.com/questions/947807/creating-multiple-instances-of-imported-mef-parts

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!