我什么时候应该使用像Ninject这样的依赖注入器

时间:2013-08-23 19:39:42

标签: c# dependency-injection dependencies inversion-of-control ninject

问题

我有一些问题需要了解我的代码中何时何地应该使用像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))));
    }

问题

何时应该使用依赖注入器?

  1. 关于构造函数注入,参数注入等。
  2. 关于对象创建(依赖注入器是否用new替换经典对象创建?)
  3. 是其他人吗?
  4. 什么时候不应该使用依赖注入器?

4 个答案:

答案 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)

如果您想了解依赖注入器并了解何时使用它们,请查看本文。我前一段时间也想过同样的事情,这篇文章给了我很多帮助。

Dependency Injection - Martin Fowler