什么是依赖注入

移动UI设计

  1 定义

  依赖注入(Depency Injection),简称DI,类之间的依赖关系由容器来负责。简单来讲a依赖b,但a不创建(或销毁)b,仅使用b,b的创建(或销毁)交给容器。

  2 例子

  为了把DI讲清楚,我们需要举一个简单例子。例子足够小,希望让你能直观的了解DI而不会陷入真实示例的泥潭。

  例子:小明要杀怪,那小明拿什么武器杀怪呢?可以用刀、也可以用拳头、斧子等。

  首先,我们创建一个演员类,名字叫“小明”,具有杀怪功能。

  namespace NoInjection.ConsoleApp{ public class Actor { private string name = "小明"; public void Kill() { var knife = new Knife(); knife.Kill(name); } }}然后,我们再创建一个武器-刀类,具有杀怪功能。

  using System;namespace NoInjection.ConsoleApp{ public class Knife { public void Kill(string name) { Console.WriteLine(#34;{name}用刀杀怪"); } }}最后,我们客户端调用演员类,执行杀怪功能。

  using System;namespace NoInjection.ConsoleApp{ class Program { static void Main(string[] args) { var actor = new Actor(); actor.Kill(); Console.ReadKey(); } }}让我们来看看输出结果:

  小明用刀杀怪通过这个例子我们可以看到,Actor类依赖Knife类,在Actor中创建Knife,执行Knife.Kill方法。我们可以回顾一下DI的定义,a依赖b,但a不创建(或销毁)b,仅使用b,显然这个不符合DI做法。

  DI下面我们详细说说DI的几种形式。

  3 形式

  3.1 构造函数注入

  首先,我们在Actor通过构造函数传入Knife。

  namespace ConstructorInjection.ConsoleApp{ public class Actor { private string name = "小明"; private Knife knife; public Actor(Knife knife) { this.knife = knife; } public void Kill() { knife.Kill(name); } }}然后,Knife类不需要变化。

  using System;namespace ConstructorInjection.ConsoleApp{ public class Knife { public void Kill(string name) { Console.WriteLine(#34;{name}用刀杀怪"); } }}最后,我们客户端来创建Actor和Knife,然后在Actor通过构造函数传入Knife。

  using System;namespace ConstructorInjection.ConsoleApp{ class Program { static void Main(string[] args) { var knife = new Knife(); var actor = new Actor(knife); actor.Kill(); Console.ReadKey(); } }}让我们来看看输出结果:

  小明用刀杀怪这个例子我们可以看到,Actor类依赖Knife类,但在Actor不创建Knife,而是通过构造函数传入Knife。

  3.2 Setter注入

  首先,我们在Actor类创建Knife属性。

  namespace SetterInjection.ConsoleApp{ public class Actor { private string name = "小明"; private Knife knife; public Knife Knife { set { this.knife = value; } get { return this.knife; } } public void Kill() { knife.Kill(name); } }}然后,Knife类不需要变化。

  using System;namespace SetterInjection.ConsoleApp{ public class Knife { public void Kill(string name) { Console.WriteLine(#34;{name}用刀杀怪"); } }}最后,我们客户端来创建Actor和Knife,然后在Actor通过属性传入Knife。

  using System;namespace SetterInjection.ConsoleApp{ class Program { static void Main(string[] args) { var knife = new Knife(); var actor = new Actor(); actor.Knife = knife; actor.Kill(); Console.ReadKey(); } }}让我们来看看输出结果:

  小明用刀杀怪这个例子我们可以看到,Actor类依赖Knife类,但在Actor不创建Knife,而是通过属性传入Knife。

  3.3 接口注入

  首先,我们在Actor类创建Knife属性并继承IActor

  namespace InterfaceInjection.ConsoleApp{ interface IActor { Knife Knife { set; get; } void Kill(); }}namespace InterfaceInjection.ConsoleApp{ public class Actor: IActor { private string name = "小明"; private Knife knife; public Knife Knife { set { this.knife = value; } get { return this.knife; } } public void Kill() { knife.Kill(name); } }}然后,Knife类不需要变化。

  using System;namespace InterfaceInjection.ConsoleApp{ public class Knife { public void Kill(string name) { Console.WriteLine(#34;{name}用刀杀怪"); } }}最后,我们客户端来创建Actor和Knife,然后在Actor通过属性传入Knife。

  using System;namespace InterfaceInjection.ConsoleApp{ class Program { static void Main(string[] args) { var knife = new Knife(); IActor actor = new Actor(); actor.Knife = knife; actor.Kill(); Console.ReadKey(); } }}接口注入方式我理解了也不是很透,感觉跟Setter注入没有什么大的差别,只是增加了一个接口定义。

  分类: ASP.NET Core开发者指南

标签: 移动UI设计