2010-06-10 234 views
6

試圖找出如何最好地處理以下情形:依賴注入和工廠

假設一個RequestContext類具有依賴於外部服務,如:

public class RequestContext : IRequestContext 
{ 
    private readonly ServiceFactory<IWeatherService> _weatherService; 

    public RequestContext(ServiceFactory<IWeatherService> weatherService, UserLocation location, string query) 
    { 
     _weatherService = weatherService; 
     ... 

什麼樣的依賴我是否應該在課堂上要求最終實例化RequestContext?這可能是ServiceFactory<IWeatherService>,但看起來不正確,或者我可以創建沿線的爲它的IRequestContextFactory

public class RequestContextFactory : IRequestContextFactory 
{ 
    private readonly ServiceFactory<IWeatherService> _weatherService; 

    public RequestContextFactory(ServiceFactory<IWeatherService> weatherService) 
    { 
     _weatherService = weatherService; 
    } 

    public RequestContext Create(UserLocation location, string query) 
    { 
     return new RequestContext(_weatherService, location, query); 
    } 
} 

然後通過構造函數注入傳遞IRequestContextFactory

這似乎是一個很好的方法,但這種方法的問題是,我認爲它阻礙了可發現性(開發人員必須瞭解工廠並實施它,這並不是很明顯)。

我錯過了更好/更容易發現的方式嗎?

回答

5

鬆散耦合的美妙之處在於我們可以不斷地隱藏以前的細節

從IRequestContext的使用者的角度來看,RequestContext及其依賴關係的存在純粹是實現細節。因爲Liskov Substitution Principle,消費者只能對付IRequestContext:

public class MyClass 
{ 
    private readonly IRequestContext reqCtx; 

    public MyClass(IRequestContext reqCtx) 
    { 
     if (reqCtx == null) 
     { 
      throw new ArgumentNullException("reqCtx"); 
     } 

     this.reqCtx = reqCtx; 
    } 

    // Implement using this.reqCtx... 
} 

只有在應用程序的Composition Root你需要最後線都在一起。下面是一個窮人的DI方法的草圖:

ServiceFactory<IWeatherService> weatherService = 
    new ServiceFactory<IWeatherService>(); 
UserLocation location = new UserLocation; 
string query = "foo"; 

IRequestContext reqCtx = new RequestContext(weatherService, location, query); 

var mc = new MyClass(reqCtx); 
+0

有趣的是,我沒有想過直接注入RequestContext,因爲它的參數在每個頁面請求(ASP.NET MVC)上都會有所不同。使用NInject通過查看查詢字符串來正確地爲我實例化類是否是一個好主意?或者我會配置NInject使用返回實例的工廠,但在基本級別只需要注入RequestContext? – andreialecu 2010-06-10 13:11:49

+0

我還不知道Ninject已經足夠回答關於這個問題的細節了,但是如果它不直接支持這個,你可以使用注入到更高級別消費者的抽象工廠自己實現這個小部分。 – 2010-06-10 13:22:33

0

工廠模式是一個衆所周知的,記錄和使用的方法。 如果您擔心其他開發者無法達到正常速度,請在代碼的(xml)文檔中輸入wikipedia's factory pattern page的鏈接。

此外,請確保您的工廠名稱很清晰 - 微軟似乎很喜歡Provider後綴。

+0

「Provider」後綴爲+1。需要重構我的工廠。 :)'提供者'爲 – andreialecu 2010-06-10 13:17:58

+1

-1。你知道_why_他們是後綴'提供者'嗎?不要盲目採用它,只是因爲MS使用它。它可能是由於完全不同的原因。 – 2010-06-10 22:59:15

+4

http://msdn.microsoft.com/en-us/library/ms972319.aspx表明它們使用Provider來指示擴展使用ASP.NET提供程序模型的ProviderBase的類。只有在這種情況下,提供者後綴纔是適當的。 – 2010-06-10 23:47:42