【问题标题】:Creating multiple instances of Imported MEF parts创建导入的 MEF 零件的多个实例
【发布时间】:2009-06-03 23:19:42
【问题描述】:

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

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

但这给了ma一个实现ILedPanel的类的单一实例。 我真正想做的是能够创建尽可能多的实例 我需要的。请注意,仅包含一个用于 ILedPanel 的导出 随时使用该软件。

(如果我使用带有 List 的导入,它给了我一个实例 对于每个实现 ILedPanel 的类)

有什么建议吗?

【问题讨论】:

  • 我不确定这是不是一个好方法,但我只是选择了 Activator.CreateInstance(Panel.GetType());

标签: c# .net mef


【解决方案1】:

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

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

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

ILedPanel panel = PanelFactory.BuildPanel();

【讨论】:

    【解决方案2】:

    所有其他答案都很老了,所以他们没有提到 MEF 中一个相对较新的功能,称为ExportFactory。这个泛型类允许您导入ExportFactory<ILedPanel> 并在需要时创建任意数量的实例,因此您的代码如下所示:

    [Import(typeof(ILedPanel)]
    public ExportFactory<ILedPanel> PanelFactory { get; set; }
    
    public ILedPanel CreateNewLedPanelInstance()
    {
        return PanelFactory.CreateExport().Value;
    }
    

    此方法还满足创建的部件所具有的任何导入。您可以阅读有关使用 ExportFactoryhere 的更多信息。

    【讨论】:

    • 这基本上是我要建议的机制的内置解决方案,任何人都可以构建自己。您实际上创建了一个具有可注入属性的工厂类。每当您调用 MEF 的填充对象方法时,它都会获得一个新实例,然后可以返回该实例。 ExportFactory 中的构建当然更好。
    【解决方案3】:

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

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

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

    尼克

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

    【讨论】:

    • 更新:此功能已作为 PartCreator 进入 MEF“Preview 7” - 有关信息,请参阅 MEF wiki (mef.codeplex.com/Wiki/…)
    • 但似乎只适用于 Silverlight
    • 这是为非 Silverlight 添加到 Preview 8 的,然后从 Preview 9 中拉出!咕噜。
    【解决方案4】:

    除非我误解了这个问题,否则它看起来可以通过简单地使用 CreationPolicy.NonShared 来解决。

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

    【讨论】:

    • 确实如此。但是只有一个类可以在任何软件发行版中实现 ILedPanel。所以这是一个单一的实例......它当然不干净
    【解决方案5】:

    看MEF自带的shapes游戏示例,里面有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 实现已注册。

    【讨论】:

      【解决方案6】:

      我认为您的意思是您想在这种情况下使用 MEF,例如服务定位器而不是依赖注入容器。尝试查看 ValueResolver 的示例

      【讨论】:

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