2015-01-02 60 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?