需要 -
这是导出类
public interface IMyExport
{
void Display();
}
public class MyExport : IMyExport
{
private Guid _id = Guid.NewGuid();
public void Display()
{
Console.WriteLine("Instance ID = "+_id);
}
}
以下是我导出类
的实例的方法public static class ExportInitialization
{
[Export("Type A", typeof(IMyExport)),
Export("Type B", typeof(IMyExport))]
public static IMyExport IceCreamExport
{
get
{
return new MyExport();
}
}
}
消费者可以通过以下方式导入特定实例
[Export]
public class ImporterA
{
private readonly IMyExport _myExport;
[ImportingConstructor]
public ImporterA([Import("Type A")]IMyExport myExport)
{
_myExport = myExport;
}
public void Display()
{
_myExport.Display();
}
}
[Export]
public class ImporterB
{
private readonly IMyExport _myExport;
[ImportingConstructor]
public ImporterB([Import("Type B")]IMyExport myExport)
{
_myExport = myExport;
}
public void Display()
{
_myExport.Display();
}
}
class Program
{
[Import]
public ImporterA ImporterA { get; set; }
[Import]
public ImporterB ImporterB { get; set; }
static void Main(string[] args)
{
new Program().Run();
}
public void Run()
{
var container = new CompositionContainer(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
container.ComposeParts(this);
ImporterA.Display();
ImporterB.Display();
Console.ReadKey();
}
}
这曾经与.Net 4.0一起使用,但是当安装.Net 4.5时 - 我得到以下ouptut
Instance ID = 78bba41a-0c48-44fc-ae69-f0ead96371f9
Instance ID = 78bba41a-0c48-44fc-ae69-f0ead96371f9
请注意,两个导入都返回相同的对象实例。我是否打破了一些关于通过静态属性导出的无证规则?
答案 0 :(得分:1)
我发现从两个不同的静态属性导出特定实例可确保返回2个不同的实例。
[Export("Type A", typeof(IMyExport))]
public static IMyExport ExportA
{
get
{
return new MyExport();
}
}
[Export("Type B", typeof(IMyExport))]
public static IMyExport ExportB
{
get
{
return new MyExport();
}
}
这很令人费解,因为在未经修改的版本中,静态getter正在每次获取时创建一个新实例。不确定这是否是4.5引入的某些C#/。Net优化的结果,或者这是否是MEF问题
答案 1 :(得分:0)
MEF属性的默认值是组件不会说他们是否每次都要关注新实例。
意思是:
ExportAttribute
未指定是否可以或应该共享导出的实例; ImportAttribute
都未指定是否应共享其导入; MEF的默认行为是,如果不禁止共享实例,它将会。这意味着,根据文档,.NET 4.5的行为是正确的:MyExport
的实例是共享的,因为任何一方都没有明确禁止共享。
我认为.NET 4.0有一个错误/差异,每次调用静态属性,导致你观察到的,即非共享实例。你依赖那个bug。我认为这个bug的起源是对于属性的一个基本的,框架范围的期望 - 让静态属性为每个属性调用创建一个新的,语义上不同的实例是非常罕见的。
我相信你应该: