我正在使用MEF來編寫來自幾個程序集的導出類型。我正在使用一個基類,它應該是派生類中指定的ImportMany
依賴項。它看起來是這樣的:MEF的ImportMany在基類中導入所有組件的所有導出 - 如何防止這種情況?
基地大會:
public abstract class BaseClass
{
[ImportMany(typeof(IDependency)]
public IEnumerable<IDependency> Dependencies { get; private set; }
protected BaseClass()
{
var catalog = GetCatalog();
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
protected abstract ComposablePartCatalog GetCatalog();
}
議會答:
[Export(typeof(BaseClass))]
public class MyA : BaseClass
{
protected override ComposablePartCatalog GetCatalog()
{
return new AssemblyCatalog(Assembly.GetExecutingAssembly());
}
}
[Export(typeof(IDependency)]
public class DependencyA1 : IDependency {}
[Export(typeof(IDependency)]
public class DependencyA2 : IDependency {}
大會B:
[Export(typeof(BaseClass))]
public class MyB : BaseClass
{
protected override ComposablePartCatalog GetCatalog()
{
return new AssemblyCatalog(Assembly.GetExecutingAssembly());
}
}
[Export(typeof(IDependency)]
public class DependencyB1 : IDependency {}
[Export(typeof(IDependency)]
public class DependencyB2 : IDependency {}
我然後撰寫一切都在底座組件:
static void Main(string[] args)
{
DirectoryCatalog catalog = new DirectoryCatalog(path, "*.dll");
var container = new CompositionContainer(catalog);
IEnumerable<BaseClass> values = container.GetExportedValues<BaseClass>();
// both BaseClass instances now have 4 Dependencies - from both Assemby A and Assembly B!
}
我遇到的,當我使用MEF撰寫既MyA
和MyB
的問題,每個包含出口IDependency
-ies從兩個組件!我只想要MyA
包含出口DependencyA1
和DependencyA2
,與MyB
相同。
我知道我可能應該爲此使用依賴注入容器,但我希望可以使用MEF嗎?
只是一些注意事項 - 用構造函數做構圖 - 我已經看到了很多,這不是一個好設計的想法。建議您的應用程序的一個部分處理與組合容器有關的所有事情,這就是所謂的* CompositionRoot *。理想情況下,您的組件應設計爲不受任何擴展性或IoC容器的影響,因此您可以獨立構建和測試它們。爲了做到這一點,雖然旋轉一個'CompositionContainer'的新實例相對便宜,但編目創建可能很昂貴。 –
另一點需要考慮的是,您正在從構造函數調用虛擬方法,這意味着您不能再保證您的'BaseClass'構造函數將完成,因爲它現在依賴於回調函數的繼承層次結構。如果你的'override'方法試圖使用你的子類類型的實例成員 - 你最終可能拋出'NullReferenceException'實例,因爲這些實例成員可能還沒有被初始化。 –
@MatthewAbbott RE構造函數中的虛擬調用,你是對的,這只是爲了這個例子。在我的「真實」應用程序中,我沒有從構造函數調用虛擬方法。 –