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

发布于 2024-07-22 05:52:18 字数 304 浏览 6 评论 0原文

目前,我的 WPF 应用程序导入了这样的部分,

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

但这为我提供了实现 ILedPanel 的类的单个实例。 我真正想做的是能够创建尽可能多的实例 我需要的。 请注意,仅包含一项 ILedPanel 导出 在任何给定时间使用该软件。

(如果我使用 List 的导入来给我一个实例 对于每个实施 ILedPanel 的班级)

有什么建议吗?

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?

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

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

发布评论

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

评论(6

撩起发的微风 2024-07-29 05:52:18

所有其他答案都相当旧,因此他们没有提到 MEF 中名为 ExportFactory。 这个通用类允许您导入 ExportFactory 并在需要时创建任意数量的实例,因此您的代码将如下所示:

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

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

此方法还满足创建的部件具有的任何导入。 您可以在此处了解有关使用 ExportFactory 类的更多信息。

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.

囚你心 2024-07-29 05:52:18

我不确定这是否是尼古拉斯所指的,但您可以导入工厂类而不是实例类,如下所示:

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

...然后在您的代码中...

ILedPanel panel = PanelFactory.BuildPanel();

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();
忆梦 2024-07-29 05:52:18

今天 MEF 中没有对此的“内置”支持,但在恢复到服务定位器之前,您可能会在这里找到一些灵感:http://blogs.msdn.com/nblumhardt/archive/2008/12 /27/container-management-application-design-prelude-where-does-the-container-belong.aspx

基本思想是将容器“导入”到需要进行动态实例化的组件中。

我们正在探索对这种情况的更直接支持。

Nick

更新:MEF 现在对此提供了实验性支持。 请参阅此博文 了解更多信息。

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.

内心旳酸楚 2024-07-29 05:52:18

除非我误解了这个问题,否则看起来只需使用 CreationPolicy.NonShared 即可解决。

这假设声明面板的代码存在于您想要面板的任何地方。 您将在具有此声明(导入)的每个类的每个实例中获得一个新的 ILedPanel 实例。

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

柒夜笙歌凉 2024-07-29 05:52:18

查看 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; }
    }
}

它演示了“按需”创建随机形状实例...我认为在您的场景中,您可以在不选择随机实现的情况下执行类似的操作,正如您所建议的,只有一种 ILedPanel 实现已注册。

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.

深海蓝天 2024-07-29 05:52:18

我认为你的意思是你想在这个实例中使用 MEF,就像服务定位器而不是依赖项注入容器。 尝试查看 ValueResolver 的示例

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

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