我确信我在这方面有点迷失......我的理解是依赖注入意味着初始化类所需的东西。例如。 如果我的控制器需要一个服务,我希望能够测试它,那么我应该为它定义两个Constructor方法......所以,我的问题是......为什么人们使用Frameworks来实现这个?我输了
public class CompaniesController : Controller
{
private ICompaniesService _service;
public CompaniesController()
{
_service = new CompaniesService();
}
public CompaniesController(ICompaniesService service)
{
_service = service;
}
答案 0 :(得分:6)
主要原因是更好地支持单元测试和模拟对象以创建受控测试。
通过不在类中指定实现,您可以在运行时“注入”实现。 (在您的示例中,ICompaniesService接口)。
在运行时,使用StructureMap,Unity或Castle Windsor等控件/依赖注入容器的反转,你可以说“嘿,任何时候有人想要一个ICompaniesService实例给他们一个新的CompaniesService对象”。
要对此类进行单元测试,您可以模拟我们的ICompaniesService并将其自己提供给构造函数。这允许您在模拟对象上设置受控方法。如果你不能这样做,那么对于CompaniesController的单元测试将仅限于使用公司服务的一个实现,这可能会影响实时数据库等,使你的单元测试既缓慢又不一致。
答案 1 :(得分:4)
人们不使用依赖注入框架来生成您在示例中提供的代码。这仍然是开发人员的工作。
当有人调用构造函数时,使用依赖注入框架。框架将注入ICompaniesService的具体实现,而不是显式调用构造函数的开发人员。
虽然它是特定产品,但nInject Homepage实际上有一些非常好的例子。
答案 2 :(得分:1)
来自Wikipedia:
没有依赖的概念 注射,需要的消费者 特定服务“ICompaniesService”以便 完成某项任务即可 负责处理 生命周期(实例化,开放和 关闭流,处置等) 那个服务。使用的概念 然而,依赖注入 服务的生命周期由。处理 依赖提供者/框架(通常是 容器)而不是消费者。 因此消费者只需要一个 参考了一个实现 服务“ICompaniesService”它需要它 完成必要的任务。
也读这个:
答案 3 :(得分:0)
人们使用依赖注入框架,因为否则你必须编写一吨无聊的重复工厂类(如果使用依赖注入,那就是)。
它可以做到,它非常非常烦人。
答案 4 :(得分:0)
我认为你的理解只是部分正确。依赖注入是“注入” 组件与其的依赖关系。它是一种更具体的控制反转形式。中 这个过程也可以在注入之前初始化一些依赖项。
使用DI,查找依赖项的责任不在组件上 (如在ServiceLoacator模式中)但最多到组件所在的容器 运行。该模式具有以下优点:
在您的代码示例中,DI容器可以在运行时通过第二个注入依赖项 构造函数。其他形式的注射也是可能的(取决于DI容器)。例如 现场注入,二次注射等
马丁·福勒有一个good article创造了DI术语
答案 5 :(得分:0)
您不必拥有DI框架,但在代码库中的某个时刻,需要实例化具体实现并将其注入到构造函数/属性中。如果你没有DI框架,它会变得非常混乱,我建议看看温莎城堡,尽管如前所述还有其他将执行相同的功能。或者,如果你可以role your own ......:)
答案 6 :(得分:0)
我会投入:
只需通过参数化函数定义即可完成依赖注入。
然而,为了使这项工作保持一致,每个人都必须真正做到这一点。许多人发现使用工厂设计模式更容易实施惯例。
依赖注入框架解决了减少编写这些工厂的样板问题。
我会说通过工厂的依赖注入是不理想的。在我看来,工厂增加了一个额外的间接层,从某种意义上说,确定性函数是确定性的,因为它们现在是输入的函数,加上你看不到的程序其余部分的状态(你的设置)仅从功能定义。工厂使代码变得更难,因为它们增加了额外的间接层我认为在许多情况下,遵循约定并通过函数参数手动注入类实际上并不太难。但是,对于大型代码库,它可能更容易通过工厂实施规则。
..有人说,有时我想知道这些大型代码群是否会如此大,如果他们没有写出这么多东西试图先发制人地解决他们根本没有的问题