[英]Dependency Injection and assembly references
我有一個我希望是MVC應用程序中依賴注入的基本問題,我一直無法找到滿意的答案。 我的應用程序包含一個MVC 3項目,一個服務層類庫(SL)和一個數據訪問類庫(DAL)。 SL和DAL都包含各自的接口和實現。 MVC項目引用了SL和DAL項目。 MVC項目將創建DAL的實現並將其注入到接受DAL接口的SL構造函數中。
我擔心的是為了讓SL接受DAL接口作為參數,它還需要對DAL項目的引用(接口碰巧存在但也是實現),這似乎違反了DI,因為現在MVC和SL項目需要引用DAL程序集。
簡而言之,將DAL接口移動到自己的項目中是否更有意義,這樣SL只需要引用接口項目而不是實現項目? MVC項目顯然需要引用接口和實現項目,DAL也需要引用接口項目。 這似乎是一種更干凈的做事方式,即使它為我的解決方案增加了另一個項目,這並沒有給我帶來太多麻煩。 我也看到了在SL中存儲DAL接口的建議,並且有DAL參考SL,但這對我來說似乎不對。 任何見解或建議都表示贊賞。 謝謝!
看看洋蔥建築:
http://jeffreypalermo.com/blog/the-onion-architecture-part-1/
http://jeffreypalermo.com/blog/the-onion-architecture-part-2/
http://jeffreypalermo.com/blog/the-onion-architecture-part-3/
讓UI程序集引用所有服務和業務邏輯程序集是完全正確的。 服務層顯然應該引用不應該依賴於任何更高級別的基礎結構程序集。
真正的組件必須將它們的接口及其實現放在單獨的程序集中。
這允許您像加載項一樣動態加載適當的實現。 通常它也是避免循環引用的唯一方法。 作為示例,DAL需要知道模型(業務類),並且模型可能希望通過DAL調用延遲加載依賴模型,這會創建循環引用(.NET禁止循環程序集引用)。 如果接口位於單獨的程序集中,則DAL和Model程序集都引用了兩個接口程序集,並通過構造函數獲取依賴項。
// Assembly: Model contracts
public interface IModelA
{
IModelB ModelB { get; }
...
}
public interface IModelB
{
...
}
public interface IModelFactory
{
IModelA CreateModelA();
IModelB CreateModelB();
}
// Assembly: DAL contracts, references Model contracts
public interface IDAL
{
IModelA LoadA(int id);
IModelB LoadB(int id);
}
// Assembly: Model implementation, references Model and DAL contracts
public class ModelA : IModelA
{
private IDAL _dal;
public ModelA (IDAL dal)
{
_dal = dal;
}
private IModelB _modelB;
public IModelB ModelB
{
get {
if (_modelB == null) {
_modelB = _dal.LoadB(5);
}
return _modelB;
}
}
}
// Assembly: DAL implementation, references Model and DAL contracts
public class DAL : IDAL
{
private IModelFactory _modelFactory;
public DAL(IModelFactory _modelFactory)
{
_modelFactory = modelFactory;
}
public IModelA LoadA(int id)
{
IModelA modelA = _modelFactory.CreateModelA();
// fill modelA with data from database
return modelA;
}
public IModelB LoadB(int id)
{
IModelB modelB = _modelFactory.CreateModelB();
// fill modelB with data from database
return modelB;
}
}
正如規則所說,只要您依賴接口而不是具體實現,它就沒問題。 所以你可以做的是將你的接口放在單獨的程序集中,並在任何你想要的地方引用它們。
引用具有混凝土類型的程序集可能是一個問題,但這取決於您要實現的目標。 通過讓服務僅依賴於抽象,您可以實現松散耦合的代碼。 這提高了可維護性。
讓BL程序集僅引用包含抽象(而不是實現)的程序集,允許您獨立部署部分軟件。 比如說您希望將軟件部署到不同的客戶,並且您有多種DA層,但不希望將所有DA風格部署到所有客戶(例如,因為他們需要為每個DA層付費,或者可能你試圖保護你的知識產權)。
因此,如果分離不是部署的關注點,則不必創建單獨的程序集。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.