2015-01-02 127 views
1

使用構造器注入,依賴被注入到消費者這樣的(至少我希望我理解正確的話):保護條款和依賴注入空對象模式和C#

public class SomeConsumer 
{ 
    private IDependency someDependency; 
    public SomeConsumer(IDependency someDependency) 
    { 
     if (someDependency != null) 
     { 
      this.someDependency = someDependency; 
     } 
     else 
     { 
      throw new ArgumentNullException("someDependency"); 
     } 
    } 

    public void Baz() 
    { 
     someDependency.DoSomething(); 
    } 
    (...) 
} 

如果我使用IDependency的空對象模式,我是否需要guard子句?或者注入一個空對象是否是錯誤的?

UPDATE: 澄清,讓我們假設我有類和接口是這樣的:

public interface IDependency 
{ 
    void DoSomething(); 
} 

public class NullDependency : IDependency 
{ 
    public void DoSomething() 
    { 
     //Do nothing... 
    } 
} 

public class RealDependency : IDependency 
{ 
    public void DoSomething() 
    { 
     Console.WriteLine("Did something"); 
    } 
} 

public class Foo 
{ 
    public void Bar() 
    { 
     IDependency dependency = new NullDependency(); 
     SomeConsumer sc = new SomeConsumer(dependency); 
     sc.Baz(); 
    } 
} 

我可以再安全地刪除從SomeConsumer保護條款,使它看起來像:

public class SomeConsumer 
{ 
    private IDependency someDependency; 
    public SomeConsumer(IDependency someDependency) 
    { 
     this.someDependency = someDependency; 
    } 

    public void Baz() 
    { 
     //if someDependency is a NullDependency, this does nothing 
     someDependency.DoSomething(); 
    } 
    (...) 
} 

或者我應該使用保護條款,因爲我不能確定null將永遠不會被注入?

回答

2

恕我直言,我會放棄在下列情況下保護條款:

  • SomeConsumer只被從你的產品中使用
  • 空對象模式徹底你的團隊和/或依賴注入容器住配置

我可能不會放棄保護條款,如:

  • 需要一個空對象不是目標受衆
  • SomeConsumer是一個開放的API的一部分,由開發者並沒有意識到空對象模式
  • 我想收到的使用充分證明從我的依賴注入容器的反饋時,它instanciates SomeConsumer,我犯了一個錯誤
0

恕我直言,它是完全正常的注入空對象,這是經常用於測試。當我不關心這種依賴關係時,我經常在單元測試中注入默認行爲的mock。

我可能會替換null檢查拋出異常或完全刪除它。無論如何,由於someDependency變量的默認值爲null,它目前不執行任何操作。

+1

我忘了添加拋出的異常,問題就更新了。 – Thaoden

1

我不喜歡在任何情況下放下守衛子句。無論誰使用這個類,所有創建的對象都應該是有效的。如果允許通過構造函數注入null,則允許構造無效對象。稍後,當某個方法被調用時,某些東西會中斷。

這不是這個班是否內部的問題。問題是你會確保在所有地方調用構造函數時都採取所有措施來產生非空值?即使你的回答是「是」,下一個問題是你爲什麼會浪費時間和精力來檢查它?

只是留下警戒條款,你會知道這個類的所有對象將被正確構造。否則,如果您無意中將null傳遞給構造函數,那麼一些完全不相關的類將會失敗,您將很難將錯誤追溯到此構造函數。

在一個相關的說明中,一些警衛子句(那些測試非零的條件)通常是重新考慮設計的原因。你可能會覺得這篇文章很有趣 - Why do We Need Guard Clauses?