目前我的 WPF 应用程序导入这样的部分
[Import(typeof(ILedPanel)]
public ILedPanel Panel { get; set; }
但这给了实现 ILedPanel 的类的单一实例。我真正想做的是能够创建我需要的尽可能多的实例。请注意,在任何给定时间,软件都只包含一个用于 ILedPanel 的导出。
(如果我使用带有 List 的导入,它为每个实现 ILedPanel 的类提供一个实例)
有什么建议么?
我不确定这是否是 Nicolas 所指的,但您可以导入工厂类而不是实例类,如下所示:
[Import(typeof(ILedPanelFactory)]
public ILedPanelFactory PanelFactory { get; set; }
...然后在您的代码中...
ILedPanel panel = PanelFactory.BuildPanel();
所有其他答案都很老了,所以他们没有提到 MEF 中一个相对较新的功能,称为ExportFactory
. 这个泛型类允许您在需要时导入ExportFactory<ILedPanel>
和创建任意数量的实例,因此您的代码如下所示:
[Import(typeof(ILedPanel)]
public ExportFactory<ILedPanel> PanelFactory { get; set; }
public ILedPanel CreateNewLedPanelInstance()
{
return PanelFactory.CreateExport().Value;
}
此方法还满足创建部件所具有的任何导入。您可以在此处阅读有关使用ExportFactory
该类的更多信息。
今天在 MEF 中没有对此的“内置”支持,但在恢复到服务定位器之前,您可能会在这里找到一些灵感:http: //blogs.msdn.com/nblumhardt/archive/2008/12/27/container -托管应用程序设计-前奏-哪里-容器-belong.aspx
基本思想是将容器“导入”到需要进行动态实例化的组件中。
我们正在探索对这种情况的更直接支持。
缺口
更新: MEF 现在对此有实验性支持。有关更多信息,请参阅此博客文章。
除非我误解了这个问题,否则它看起来可以通过简单地使用 CreationPolicy.NonShared 来解决。
这假设声明面板的代码存在于您想要面板的任何地方。您将在具有此声明(导入)的每个类的每个实例中获得一个新的 ILedPanel 实例。
查看 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 实现注册。
我认为你的意思是你想在这种情况下使用 MEF,比如服务定位器,而不是依赖注入容器。尝试查看 ValueResolver 的示例