【发布时间】:2013-09-08 08:37:43
【问题描述】:
考虑以下代码示例,该示例使用 MEF 创建 Importer 类型的对象,该对象导入 ImporterExporter 类型的对象,该对象又导入 Exporter 类型的对象,即 Importer -> ImporterExporter -> Exporter。该目录由CompositionUtility 管理(对于此示例显然已简化)。
我知道 MEF 将递归解析导入部件的导入。但是,因为我希望可以选择独立地实例化这些类中的每一个,所以每个具有导入的类也会在其构造函数中组合自己来解析这些导入。
using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;
namespace MefRecursionSample
{
class Program
{
static void Main(string[] args)
{
// var importerExporter = new ImporterExporter(); // include this and composition will work
var importer = new Importer();
Console.Write(importer.ImporterExporter.Exporter.Value); // should print 7
Console.ReadKey();
}
}
class CompositionUtility
{
static CompositionUtility()
{
var executingAssembly = Assembly.GetExecutingAssembly();
var assemblyCatalog = new AssemblyCatalog(executingAssembly);
_compositionContainer = new CompositionContainer(assemblyCatalog);
}
private static CompositionContainer _compositionContainer;
private static bool _isComposing;
public static void Compose(object part)
{
_compositionContainer.ComposeParts(part);
}
}
class Importer
{
public Importer()
{
CompositionUtility.Compose(this);
}
[Import]
public ImporterExporter ImporterExporter { get; set; }
}
[Export]
class ImporterExporter
{
public ImporterExporter()
{
CompositionUtility.Compose(this);
}
[Import]
public Exporter Exporter { get; set; }
}
[Export]
class Exporter
{
public int Value { get { return 7; } }
}
}
按原样运行代码会导致组合错误“无法重新组合 MefRecursionSample.Importer 类型的 ComposablePart....”,显然是因为我试图明确组合 MEF 也想要组合的东西。
令我惊讶的是,当我包含 Main 方法的第一行时,即在没有 MEF 的情况下创建 ImporterExporter 类型的对象时,这种“双重组合”不再导致异常。这是为什么呢?
另外,我怎样才能使它工作,以便我可以独立地实例化这些中的每一个,同时也让它们在像示例中那样被链接时自行组合。我想我会在CompositionUtility 上引入一个布尔标志_compositionInProgress,并在设置该标志以避免递归组合时立即从Compose() 返回。有没有更好的办法?
【问题讨论】: