问题
我有一些问题需要了解我的代码中何时何地应该使用像Ninject这样的依赖注入器。
代码
比方说,我们有以下代码:
//WITHOUT NINJECT:
IMailSender mailSender = new MockMailSender();
//WITH NINJECT:
IMailSender mailSender = kernel.Get<IMailSender>();
这个不是依赖注入,所以在这种情况下使用Ninject是否有意义?
另一个例子显示了我的代码如何通过使用依赖注入器来搞砸了:
public void CalculateRevenueRecognitions(IContract contract)
{
//WITH NINJECT
var kernel = new StandardKernel(new DefaultModule());
var arguments = new List<IParameter>
{
new ConstructorArgument("amount",contract.Revenue),
new ConstructorArgument("date", contract.WhenSigned)
};
contract.AddRevenueRecognition(kernel.Get<IRevenueRecognition>(arguments.ToArray()));
//WITHOUT NINJECT:
contract.AddRevenueRecognition(new RevenueRecognition(contract.Revenue, contract.WhenSigned))));
}
问题
何时应该使用依赖注入器?
什么时候不应该使用依赖注入器?
答案 0 :(得分:7)
基本前提是不依赖于具体的类(就像你说的新的具体类)和注入实现(通过接口)。这取决于您正在执行的具体任务以及在什么条件下(Windows服务,WCF服务,Asp.Net),但在大多数情况下,您有一个接口,其中包含您希望公开公开的所有方法,如此
public interface IBar {
void DoStuff();
}
然后,然后使用Ninject将这些绑定到特定的类,即
Bind<IBar>().To<BarClass>();
因此,在启动时,Ninject将获得配置的实现。这方面的优点是您的实现已配置,因此只要它实现接口,就可以很容易地交换到另一个实现。所以如果你现在想要使用另一个类而不是BarClass,你可以重新绑定它,即
。Bind<IBar>().To<NewBarClass>();
因此,只要您需要使用此NewBarClass,就可以像这样传递它
public class UserOfNewBarClass {
public UserOfNewBarClass(IBar newBarClass) {
}
// Use the IBar interface
}
此外,您可以在测试时模拟接口,这意味着您可以隔离单个具体类并完全隔离测试它们。你可以做更复杂的事情,你可以在以后学习,比如基于属性值的绑定和对你注入的内容的条件绑定。
关于入口点,请参阅这些
WCF - http://www.aaronstannard.com/post/2011/08/16/dependency-injection-ninject-wcf-service.aspx
MVC - http://www.shahnawazk.com/2010/12/dependency-injection-in-aspnet-mvc-3.html
Windows服务 - Using Ninject with a Windows Service
起初很难理解,但Container(在本例中为Ninject)根据您指定的绑定计算出要注入的实现。最终目标是注入您的类所需的所有内容,以便执行它的方法,以便您可以单独测试它(它还有助于保持类清洁和整洁)。首选方法是通过构造函数注入,因为类在创建时将具有所有依赖项。物业注入当然是可行的,但与属性一样,你无法保证它已被设置。
答案 1 :(得分:3)
我过去曾广泛使用过依赖注入框架。地狱我甚至写了一个(比Ninject更快地执行注册和分辨率光年,虽然我很乐意借用Ninjas,KiteShields Shuriken等有趣的单元测试模型)。
这些天我几乎没有使用依赖注入框架。因为如果我从(重)框架的使用中学到了一件事,那就是:
你有技术问题。您搜索并试验将为您解决问题的框架。你选择一个并在任何地方使用它。
现在你有2个问题。你的依赖注入框架只是让你对你的整个代码库产生了很大的依赖。
Greg Young(http://skillsmatter.com/podcast/agile-testing/simple-is-better)有一个很棒的SkillsMatter演示文稿,其中有关于框架的陈述和意见可能看起来有点偏向极端,但其中不少,我已经学到了很多,我同意。
答案 2 :(得分:1)
问题是,我现在无法想象我会自己使用依赖注入的场景。我更熟悉使用Inversion of Control(使用DI的IoC容器)的情况。在这种情况下,您的代码实际上非常干净,因为您不必为实例调用注入器。 IoC容器将为您完成。
所以我会考虑,如果使用IoC / DI而不仅仅使用DI不是更好。最后,许多成功的框架使用这种组合,不使用它们中的一个(假设它们完全使用DI,因为实际上有另一种模式可以与IoC结合)。
答案 3 :(得分:0)
如果您想了解依赖注入器并了解何时使用它们,请查看本文。我前一段时间也想过同样的事情,这篇文章给了我很多帮助。