Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 创建导入MEF零件的多个实例_C#_.net_Mef - Fatal编程技术网

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

C# 创建导入MEF零件的多个实例,c#,.net,mef,C#,.net,Mef,目前,我的WPF应用程序导入了如下部件 [Import(typeof(ILedPanel)] public ILedPanel Panel { get; set; } 但这给了ma一个实现ILedPanel的类的单一入口。 我真正想做的是能够创建尽可能多的实例 我需要的。请注意,仅包含一个ILedPanel导出 在任何给定时间使用软件 (如果我使用一个import with List,它提供了一个实例 对于实现ILedPanel的每个类) 有什么建议吗?我想您的意思是希望在这个实例中像服务定位

目前,我的WPF应用程序导入了如下部件

[Import(typeof(ILedPanel)]
public ILedPanel Panel { get; set; }
但这给了ma一个实现ILedPanel的类的单一入口。 我真正想做的是能够创建尽可能多的实例 我需要的。请注意,仅包含一个ILedPanel导出 在任何给定时间使用软件

(如果我使用一个import with List,它提供了一个实例 对于实现ILedPanel的每个类)


有什么建议吗?

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

目前MEF中没有对此的“内置”支持,但在恢复到Service Locator之前,您可能会在这里找到一些灵感:

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

我们正在探索对该场景更直接的支持

尼克


更新:MEF现在对此有实验支持。有关更多信息,请参阅。

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

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

public ILedPanel CreateNewLedPanelInstance()
{
    return PanelFactory.CreateExport().Value;
}
…然后在以后的代码中

ILedPanel panel = PanelFactory.BuildPanel();

查看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; }
    }
}
[导出]
公共类形状因子
{
private readonly Random=new Random((int)DateTime.Now.Ticks);
[进口]
专用ICompositionService CompositionService{get;set;}
公共IShape GetRandomShape()
{
var shapeRetriever=新的shapeRetriever();
合成服务满意度导入(shapeRetriever);
int randomIndex=random.Next(shapeRetriever.PossibleShapes.Length);
返回shapeRetriever.PossibleShapes[randomIndex].GetExportedObject();
}
私有类ShapeRetriever
{
[导入数量(RequiredCreationPolicy=CreationPolicy.NonShared)]
公共导出[]可能的图形{get;set;}
}
}

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

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


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

所有其他答案都非常陈旧,因此它们没有提到MEF中一个相对较新的特性,名为。此泛型类允许您导入
ExportFactory
,并在需要时创建任意数量的实例,因此您的代码如下所示:

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

public ILedPanel CreateNewLedPanelInstance()
{
    return PanelFactory.CreateExport().Value;
}
[导入(typeof(ILedPanel)]
公共ExportFactory PanelFactory{get;set;}
公共ILedPanel CreateNewLedPanelInstance()
{
返回PanelFactory.CreateExport()值;
}

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

我不确定这是一种好方法,但我只是使用了Activator.CreateInstance(Panel.GetType());这是真的。但是只有一个类在软件的任何发行版中实现了ILedPanel。因此,这是一个单独的实例……它并不是毫无疑问的更新:此功能已作为PartCreator进入MEF“Preview 7”-有关信息,请参阅MEF wiki()但仅对于Silverlight,它看起来是被添加到非Silverlight的Preview 8中,然后从Preview 9!Grrr中提取出来的。这基本上是我要建议的机制的内置解决方案,任何人都可以构建self。实际上,您创建了一个具有可注入属性的工厂类。无论何时调用MEF的填充对象方法,它都会这是一个可以返回的新实例。内置ExportFactory当然更好。