4

问题

我有一些问题要理解在我的代码中何时何地我应该使用像 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. 关于对象创建(依赖注入器是否用新对象替换经典对象创建?)
  3. 其他人呢?

什么时候不应该使用依赖注入器?

4

3 回答 3

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 服务 -将 Ninject 与 Windows 服务一起使用

一开始很难理解,但容器(在本例中为 Ninject)会根据您指定的绑定确定要注入的实现。最终目标是注入您的类所需的一切以执行它的方法,以便您可以单独测试它(它还有助于保持类清洁和整洁)。首选方式是通过构造函数注入,因为类在创建时将具有其所有依赖项。属性注入当然是可行的,但与属性一样,您不能真正保证它已被设置。

于 2013-08-23T20:14:25.793 回答
3

我过去广泛使用过依赖注入框架。天哪,我什至写了一个(它执行注册和解析比 Ninject 快光年,尽管我很高兴借用它有趣的 Ninjas、KiteShields Shuriken 等单元测试模型)

这些天我几乎没有使用依赖注入框架。因为如果我从使用(重)框架中学到了一件事,那就是:

你有技术问题。您搜索并尝试可以为您解决问题的框架。您选择一个并在任何地方使用它。

现在你有两个问题。您的依赖注入框架只是导致您对整个代码库产生很大的依赖。

Greg Young ( http://skillsmatter.com/podcast/agile-testing/simple-is-better )有一个很棒的 SkillsMatter 演讲,关于框架的陈述和意见可能看起来有点极端,但也不少其中,我已经学会了艰难的方式,我同意。

于 2013-08-24T00:04:13.383 回答
1

问题是,我现在无法想象我会单独使用依赖注入的场景。我更熟悉使用控制反转(使用 DI 的 IoC 容器)的情况。在这种情况下,您的代码实际上非常干净,因为您不必为实例调用注入器。IoC 容器将为您完成。

所以我会考虑,如果使用 IoC/DI 而不是仅使用 DI 不是更好。最后,许多成功的框架都使用了这种组合,没有一个只使用一对中的一个(假设它们完全使用 DI,因为实际上还有另一种模式可以与 IoC 组合)。

于 2013-08-23T20:02:35.123 回答