2014-01-24 340 views
2

如果我有最佳实践

IMyService _myService; 
public MyController(IMyService myService){ 
    _myService = myService; 
} 

和我使用统一说,解决我的依赖......

的是它是否为myService是空的最佳实践如果是的话,我应该抛出一个避免或创建一个新的具体实现?

+3

不会统一抛出类似*的东西无法解析IMyService依赖*异常?对于手动插入依赖关系,你可以添加空值检查,并且存在ArgumenNullException,如果参数不应该为空,你应该抛出它。 –

+1

除非空值表示依赖关系的有效状态,否则我不会说,事实上,添加一个'Contract 。需要“或警戒以确保它不为空 - 这将是DI设置中的一个错误。 – StuartLC

回答

2

首先,Unity不会提供null作为参数值。它要么将创造IMyService注册类型的实例,否则会抛出异常:

的例外是:出现InvalidOperationException - 类型IMyService不 可访问的构造函数。


在异常时,该容器是:

解决Foo.MyController,(无)

解决构造 Foo.MyController(Foo.IMyService为myService的参数 “为myService” )解决 Foo.IMyService,(无)

所以,没有什么可担心的null由Unity注入(或其他依赖注入框架)。但是,如果控制器可以手动实例化,则有可能有人将null传递给构造函数。通过null是一种非常难闻的气味 - 这意味着系统中出现了问题。所以,最好的办法是检查服务价值,并抛出ArgumentNullException:

public MyController(IMyService myService) 
{ 
    if (myService == null) 
     throw new ArgumentNullException("myService"); 

    _myService = myService; 
} 

如果服务的注入应是可选的。那么我建议你用属性注入而不是构造函数注入

+0

是的,我在谈论如果有人试图创造一个我的对象。我知道解析器不会提供null。所以看起来我应该抛出一个异常而不是创造一个真实。 – Simon

+0

@Simon你可以使用Poor Man的依赖注入(即创建无参数构造函数,它将创建服务的默认实例并将其传递给当前构造函数),但是如果有人通过错误的参数值,仍然需要检查服务是否为null并抛出。 –

+1

想要避免可怜的人。只是想仔细检查检查为空的最佳做法,所以感谢您的答案。 – Simon

1

如果可以将依赖关系设置为null(在这种情况下,顺便说明,它不是依赖关系),那么应该将其设置为可选参数。

IMyService _myService; 
public MyController(IMyService myService = null){ 
    _myService = myService; 
} 

在所有其他情况下,抛出一个ArgumentNullException

+0

我永远不会希望它为空,所以会抛出异常。谢谢 – Simon

1

不,如果您正在使用DI框架,框架必须在无法解决依赖关系时抛出异常。你永远不会创建一个具体的实现,它是你的依赖关系的一个使用者的全部使用点。想象一下,你加:

if (myServices == null) _myService = new ConcreteService() 

如果你这样做,当你做了该控制器的单元测试,如果你选择,当你帕萨特空IMyService测试方案中,您将无法嘲笑那个对象,因为你没有inyecting它。

+0

确实。现在就写我的测试来检查异常! – Simon