我正在尝试测试MEF的单实例合成功能。导出使用[PartCreationPolicy(CreationPolicy.Shared)]
,而导入使用[ImportMany(typeof(IPartOfThePuzzle), RequiredCreationPolicy = CreationPolicy.Shared)]
。
我正在运行测试,并从控制台应用程序中的两个不同类中导入相同的零件。但是,IPartOfThePuzzle实现的两个实例似乎并不相同。看来MEF正在第二次调用中重新实例化该对象。
下面是我所拥有的。
Part1.DLL:
[PartCreationPolicy(CreationPolicy.Shared)]
[Export(typeof(IPartOfThePuzzle))]
class Piece1 : IPartOfThePuzzle
{
string _prop1;
public string SomeProp { get => _prop1; set => _prop1 = value; }
public Piece1()
{
Console.WriteLine("Piece1 instantiated, setting Prop value to 'First Part " +
"Original Value'");
_prop1 = "First Part Original Value";
}
}
Part2.DLL:
[PartCreationPolicy(CreationPolicy.Shared)]
[Export(typeof(IPartOfThePuzzle))]
class Piece2 : IPartOfThePuzzle
{
string _prop1;
public string SomeProp { get => _prop1; set => _prop1 = value; }
public Piece2()
{
Console.WriteLine("Piece2 instantiated, setting Prop value to 'Second Part " +
"Original Value'");
_prop1 = "Second Part Original Value";
}
}
Console.exe> GetParts.cs
public class GetParts
{
[ImportMany(typeof(IPartOfThePuzzle))]
public IPartOfThePuzzle[] Pieces { get; set; }
public GetParts()
{
var catalog = new AggregateCatalog();
catalog.Catalogs.Add(
new DirectoryCatalog(
@"C:\PuzzlePieces"
)
);
CompositionContainer container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
}
Console.exe> GetPartsAgain.cs
public class GetPartsAgain
{
[ImportMany(typeof(IPartOfThePuzzle))]
public IPartOfThePuzzle[] Pieces { get; set; }
public GetPartsAgain()
{
var catalog = new AggregateCatalog();
catalog.Catalogs.Add(
new DirectoryCatalog(
@"C:\PuzzlePieces"
)
);
CompositionContainer container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
}
最后是Console.exe> Program.cs
static void Main(string[] args)
{
GetParts firstImport = new GetParts();
Console.WriteLine($"Initial value from First Import: {firstImport.Pieces[0].SomeProp}");
firstImport.Pieces[0].SomeProp = "First Import Overwritten Value";
Console.WriteLine($"Overwritten from First Import: {firstImport.Pieces[0].SomeProp}");
Console.WriteLine("- - - - - - - - - - - - - - - - - - - - - - - - -");
GetPartsAgain secondImport = new GetPartsAgain();
Console.WriteLine($"Value from Second Import: {secondImport.Pieces[0].SomeProp}");
Console.ReadLine();
}
控制台输出:
输出显示碎片被实例化了两次(对于GetParts一次,对于GetPartsAgain一次)。文档,博客和在线论坛表示,这是防止多个实例的方法,但我认为我的理解不足。你能帮我理解那是什么吗?