簡體   English   中英

依賴注入和程序集引用

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM