2015-02-23 29 views
0

我目前正在努力瞭解如何在控制器類外使用依賴注入模式。依賴注入與多層應用程序

例如說,我有以下控制器:

public class TestController : Controller { 

    ILog logger; 

    public TestController(ILog log) { 

    logger = log; 

    } 

    public string TestMethod() { 

    businessLayer businessLayer = new businessLayer(); 

    return businessLayer.DoSomethingAndLogIt(); 

    } 

} 

據我所知,在大多數情況下是不能使用構造函數注入控制器類之外。因此不可能直接使用ILOG實現,即insdie「businesslayer」類。

一個簡單的解決方案,我可以想像如下:

public class TestController : Controller { 

    ILog logger; 

    public TestController(ILog log) { 

    logger = log; 

    } 

    public string TestMethod() { 

    businessLayer businessLayer = new businessLayer(logger); 

    return businessLayer.DoSomethingAndLogIt(); 

    } 

} 

所以傳遞的依賴從控制器到下伏層。但這是最好的方式嗎?是否有更好的解決方案讓我的businessLayer級訪問ILog實現?

Thx!

回答

3

據我所知,在大多數情況下,不可能使用構造函數 注入控制器類之外。

這是不正確的。您應該爲所有組件(包含行爲的應用程序中的每個類)使用構造器注入。

依賴注入是關於將相關服務/組件注入消耗組件。所以這意味着你不應該在控制器中新增businesslayer類;你應該使用構造函數注入它。通過創建此依賴關係,您違反了Dependency Inversion Principle,這會導致高耦合。這又使得你的代碼更難以測試,並且使得更難控制器更加難以應用橫切問題(如日誌記錄,審計追蹤,事務管理等)到系統中。

因此,不可能直接使用ILog實現 插入「businesslayer」類。

錯誤。應該將ILog實現注入到businesslayer類的構造函數中。

長話短說,你的控制器看起來應該是這樣:

public class TestController : Controller { 
    IBusinessLayer businessLayer; 

    public TestController(IBusinessLayer bl) { 
    this.businessLayer = bl; 
    } 

    public string TestMethod() { 
    return businessLayer.DoSomethingAndLogIt(); 

}}

由於TestController似乎並沒有直接使用ILog,它不應該被注入到它的構造。 ILog是業務層類的實現細節,實現細節不應泄露給消費者(這又違反了依賴性倒置原則)。

+0

Thx!有一件事我不明白的是IBusinessLayer如何使用ILog實現。但是大多數DI容器似乎能夠在註冊時解決這個問題。 http://simpleinjector.readthedocs.org/en/latest/using.html#automatic-constructor-injection-auto-wiring – mhtsbt 2015-02-24 07:12:20

+0

@Matthias:這不是關於DI容器。每個類只需接受它(直接)需要的依賴關係作爲構造函數參數,並在應用程序的啓動路徑中構建完整的對象圖([Composition Root](http://blog.ploeh.dk/) 2011/07/28/CompositionRoot /))。你不需要一個DI容器來做到這一點,它甚至可以有利於不使用容器。另一方面,DI容器可以幫助使您的Composition Root更加可維護。 – Steven 2015-02-24 08:05:26