zoukankan      html  css  js  c++  java
  • 手动依赖注入(二)

      首先通过下面简单的例子理解依赖注入思想。假如你正在玩一个游戏,勇士们为荣耀而战。首先需要为我们的勇士装备合适的武器。

     1 using System;
    2 using System.Collections.Generic;
    3 using System.Linq;
    4 using System.Text;
    5
    6 namespace Inject
    7 {
    8 /// <summary>
    9 ///
    10 /// </summary>
    11 public class Sword
    12 {
    13 public void Hit(string target)
    14 {
    15 Console.WriteLine("Hit the target {0} by sword", target);
    16 }
    17 }
    18 }

      接着,创建类Samurai来表示勇士。为攻击敌人,我们创建一个攻击方法Attack。当这个方法被调用时,勇士将用刀攻击对手。

     1 using System;
    2 using System.Collections.Generic;
    3 using System.Linq;
    4 using System.Text;
    5
    6 namespace Inject
    7 {
    8 /// <summary>
    9 /// 勇士
    10 /// </summary>
    11 public class Samurai
    12 {
    13 private Sword _sword;
    14
    15 public Samurai()
    16 {
    17 _sword = new Sword();
    18 }
    19
    20 public void Attack(string target)
    21 {
    22 _sword.Hit(target);
    23 }
    24 }
    25 }

      创建勇士参加战斗。

     1 using System;
    2 using System.Collections.Generic;
    3 using System.Linq;
    4 using System.Text;
    5
    6 namespace Inject
    7 {
    8 class Program
    9 {
    10 static void Main(string[] args)
    11 {
    12 Samurai s = new Samurai();
    13 s.Attack("enemy");
    14
    15 Console.ReadKey();
    16 }
    17 }
    18 }

      如果想为勇士装备其它的武器,该如何做呢?因为Sword 对象在Samurai的构造函数中被创建,所以我们不得不修改类的实现。
      当一个类依赖一个实例,称为紧耦合(tightly coupled)。在上面例子中Samurai类相对于Sword类是紧耦合的当类是紧耦合,在没有修改实现的情况下,被依赖项是不能被交换的。为了避免紧耦合,我们可以使用接口提供间接层。

      创建武器接口。

     1 using System;
    2 using System.Collections.Generic;
    3 using System.Linq;
    4 using System.Text;
    5
    6 namespace Inject
    7 {
    8 /// <summary>
    9 /// 武器
    10 /// </summary>
    11 public interface IWeapon
    12 {
    13 void Hit(string target);
    14 }
    15 }

      接着,修改类Sword实现接口IWeapon。

     1 using System;
    2 using System.Collections.Generic;
    3 using System.Linq;
    4 using System.Text;
    5
    6 namespace Inject
    7 {
    8 /// <summary>
    9   ///
    10   /// </summary>
    11 public class Sword : IWeapon
    12 {
    13 public void Hit(string target)
    14 {
    15 Console.WriteLine("Hit the target {0} by sword", target);
    16 }
    17 }
    18 }

      修改Samurai类。

     1 using System;
    2 using System.Collections.Generic;
    3 using System.Linq;
    4 using System.Text;
    5
    6 namespace Inject
    7 {
    8 /// <summary>
    9   /// 勇士
    10   /// </summary>
    11 public class Samurai
    12 {
    13 private IWeapon _weapon;
    14
    15 public Samurai()
    16 {
    17 _weapon = new Sword();
    18 }
    19
    20 public void Attack(string target)
    21 {
    22 _weapon.Hit(target);
    23 }
    24 }
    25 }

      这样勇士可以使用不同的武器,但是Sword还是在Samurai的构造函数中被创建,Samurai 类相对于Sword类还是紧耦合的。为了让勇士使用其它的兵器,我们还要修改类Samurai的实现。

      将Sword作为参数传递给Samurai的构造函数。

     1 using System;
    2 using System.Collections.Generic;
    3 using System.Linq;
    4 using System.Text;
    5
    6 namespace Inject
    7 {
    8 /// <summary>
    9   /// 勇士
    10   /// </summary>
    11 public class Samurai
    12 {
    13 private IWeapon _weapon;
    14
    15 public Samurai(IWeapon weapon)
    16 {
    17 _weapon = weapon;
    18 }
    19
    20 public void Attack(string target)
    21 {
    22 _weapon.Hit(target);
    23 }
    24 }
    25 }

      这样,我们可以通过Samurai的构造函数注入Sword,这就是依赖注入。

      接着,为勇士创建新的武器镖。

     1 using System;
    2 using System.Collections.Generic;
    3 using System.Linq;
    4 using System.Text;
    5
    6 namespace Inject
    7 {
    8 /// <summary>
    9   ///
    10   /// </summary>
    11 public class Shuriken : IWeapon
    12 {
    13 public void Hit(string target)
    14 {
    15 Console.WriteLine("Hit the target {0} by shuriken", target);
    16 }
    17 }
    18 }

      接着,创建军队。

     1 using System;
    2 using System.Collections.Generic;
    3 using System.Linq;
    4 using System.Text;
    5
    6 namespace Inject
    7 {
    8 class Program
    9 {
    10 static void Main(string[] args)
    11 {
    12 // 使用刀
    13 Samurai s1 = new Samurai(new Sword());
    14 s1.Attack("enemy");
    15
    16 // 使用镖
    17 Samurai s2 = new Samurai(new Shuriken());
    18 s2.Attack("enemy");
    19
    20 Console.ReadKey();
    21 }
    22 }
    23 }

      这就是手动依赖注入。每次创建一个Samurai,需要先创建实现了IWeapon接口的对象,传递给Samurai的构造函数。现在我们改变勇士使用的武器,就不用再修改Samurai类。Samurai被分离出来,我们可以创建新的武器而不关心Samurai的代码。

      手动依赖注入对于小项目是有效的策略,但是随着应用程序的大小和复杂性的增长,关联对象将变得越来越繁杂。接下来我们将使用Ninject实现依赖注入。

     

    参考资料:

    http://ninject.codeplex.com/wikipage?title=Dependency%20Injection%20By%20Hand&referringTitle=User%20Guide

  • 相关阅读:
    AWS研究热点:BMXNet – 基于MXNet的开源二进神经网络实现
    python数字图像处理(19):骨架提取与分水岭算法
    深度学习基石:一篇文章理解反向传播
    Densely semantically aligned person re-identification
    NPU TPU
    滤波、形态学腐蚀与卷积(合集)
    当神经网络撞上薛定谔:混合密度网络入门
    ubuntu 上配置端口转发
    插值法
    Linux终端复用神器-Tmux使用梳理
  • 原文地址:https://www.cnblogs.com/libingql/p/2389763.html
Copyright © 2011-2022 走看看