.net MEF如何获取非共享实例引用
最近,我在WPF应用程序中使用MEF时遇到了一个问题。我创建了几个类,如下所示<代码>部分类型设置为.net MEF如何获取非共享实例引用,.net,wpf,prism,mef,.net,Wpf,Prism,Mef,最近,我在WPF应用程序中使用MEF时遇到了一个问题。我创建了几个类,如下所示部分类型设置为CreationPolicy.NonShared,这样将有两个不同的对象导入到ClassA和ClassB [Export] [PartCreationPolicy(CreationPolicy.NonShared)] public class Part { public int Id { get; set; } } [Export] public class ClassA { [Impo
CreationPolicy.NonShared
,这样将有两个不同的对象导入到ClassA和ClassB
[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class Part
{
public int Id { get; set; }
}
[Export]
public class ClassA
{
[Import]
public Part PartA { get; set; }
}
[Export]
public class ClassB
{
[Import]
public Part PartB { get; set; }
}
我在下面写了一段代码来描述我的问题
[Export]
class Program
{
[Import]
public ClassA A { get; set; }
[Import]
public ClassB B { get; set; }
[ImportMany(AllowRecomposition = true)]
public IEnumerable<Part> AllParts { get; set; }
static void Main(string[] args)
{
var catalog = new AssemblyCatalog(typeof(Program).Assembly);
var container = new CompositionContainer(catalog);
var prog = container.GetExportedValue<Program>();
foreach (var part in prog.AllParts)
{
// Do something for Part instances.
// I want to get all Part instances created by MEF which have imported to ClassA and ClassB.
// However, it comes a list with a brand new Part instance.
}
}
}
[导出]
班级计划
{
[进口]
公共类A{get;set;}
[进口]
公共类B{get;set;}
[进口数量(AllowRecomposition=true)]
公共IEnumerable所有部分{get;set;}
静态void Main(字符串[]参数)
{
var catalog=新的AssemblyCatalog(typeof(Program).Assembly);
var容器=新的合成容器(目录);
var prog=container.GetExportedValue();
foreach(项目所有部分中的变量部分)
{
//为零件实例执行某些操作。
//我想得到所有由MEF创建的零件实例,它们已经导入到ClassA和ClassB。
//但是,它是一个带有全新零件实例的列表。
}
}
}
因此,将有ClassA、ClassB和导入程序对象的零件清单。事实上,我想要得到的是MEF容器创建的所有零件。但是,它是一个带有全新零件实例的列表
我理解这可能是因为CreationPolicy.NonShared
我指定给Part
类。但即使我试图在container.Catalog.Parts
中找到它们,我也只在其中找到了一个Part
实例。这让我很困惑。根据我的理解,容器应该包含它创建的对象的所有引用,因为我已经指定了AllowRecomposition=true
。我找到了一个证据来证明这一点。它说:
容器和零件参考
我们相信.Net垃圾收集器是实现这一目标的最佳工具
适当的清理。但是,我们还需要提供一个具有确定性行为的容器。因此,除非满足以下条件之一,否则容器不会保存对其创建的零件的引用:
- 该零件被标记为共享
- 该部件实现IDisposable
- 一个或多个导入配置为允许重新编译
Part
type实例零件
实例ImportMany
不会做你认为它会做的事
考虑以下几点:
public interface IMyInterface
{
int Id { get; }
}
[Export(typeof(IMyInterface))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class Part1 : IMyInterface
{
public int Id { get; private set; }
}
[Export(typeof(IMyInterface))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class Part2 : IMyInterface
{
public int Id { get; private set; }
}
[Export]
public class ClassA
{
[ImportMany]
public IEnumerable<IMyInterface> Parts { get; set; }
}
class Program
{
static void Main(string[] args)
{
var catalog = new AssemblyCatalog(typeof(Program).Assembly);
var container = new CompositionContainer(catalog);
var a = container.GetExportedValue<ClassA>();
// ...
}
}
公共接口IMyInterface
{
int Id{get;}
}
[导出(类型(IMyInterface))]
[PartCreationPolicy(CreationPolicy.NonShared)]
公共类第1部分:IMyInterface
{
public int Id{get;private set;}
}
[导出(类型(IMyInterface))]
[PartCreationPolicy(CreationPolicy.NonShared)]
公共类第2部分:IMyInterface
{
public int Id{get;private set;}
}
[出口]
甲级公共课
{
[进口数量]
公共IEnumerable部分{get;set;}
}
班级计划
{
静态void Main(字符串[]参数)
{
var catalog=新的AssemblyCatalog(typeof(Program).Assembly);
var容器=新的合成容器(目录);
var a=container.GetExportedValue();
// ...
}
}
此时,a.Parts
属性将包含两个实例:一个Part1
和一个Part2
因此,ImportMany
的目的不是获取以前导出的所有实例,而是获取导出接口的每个导出的新实例
至于您提出的如何获取所有导出的非共享实例的问题,我认为这是不可能的,因为这就是非共享的关键所在谢谢您的回答。从你所说的,你的意思是MEF在这一点上只是一个工厂吗?我认为MEF作为一个容器,应该以某种方式保存引用。请注意我问题中的报价。它还说,即使在某些情况下没有共享导出,容器也会保存引用。您的代码有利于对象创建。然而,我实际上想做的是将所有非共享的文件导出到一个地方,以便在一个地方执行一些常见的操作。关于问题中的引用,在内部保留引用并不一定意味着有办法将它们放入列表中。也许它们只能用于重新编译。@Lucax我理解你的问题,正如我在回答中所说的,我认为这是不可能的。(即使是这样,也肯定不是用
ImportMany
完成的)也许如果您向我们提供更多关于您到底想要实现什么(即为什么需要这些实例)的详细信息,我们可以给您一个更好的建议。谢谢,Venemo。在您的帮助下,我发现不可能对非共享实例执行此操作。最后,我更改了我的设置,将它们设置为共享。