考慮使用MEF創建類型Importer
的對象的以下代碼示例,該對象導入ImporterExporter
類型的對象,該對象又導入Exporter
類型的對象,即Importer -> ImporterExporter -> Exporter
。該目錄由CompositionUtility
(在本例中明顯簡化)管理。如何處理MEF中的遞歸組合?
我知道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()
返回,當標誌設置爲避免遞歸組合時。有沒有更好的辦法?
我真的很想在它的構造器中編寫一個對象(除非已經在構圖中),所以類的用戶不必擔心MEF的構成,並且可以像使用其他類一樣使用該類。此外,這將有可能將構圖引入到現有的類中。 – PersonalNexus 2012-02-06 19:40:33