MVC+EF6教程六:使用DI进行解耦

如果大家研究一些开源项目,会发现无处不在的DI(Dependency Injection依赖注入)。
本篇文章将会详细讲述如何在MVC中使用Ninject实现DI

文章提纲

  • 场景描述 & 问题引出
  • 第一轮重构
  • 引入Ninject
  • 第二轮重构
  • 总结

场景描述 & 问题引出

DI是一种实现组件解耦的设计模式。
先模拟一个场景来引出问题,我们直接使用Ninject官网的示例:一群勇士为了荣耀而战。
首先,我们需要一件合适的武器装备这些勇士。

public class Sword 
{
  public void Hit(string target)
  {
     Console.WriteLine("Chopped {0} clean in half", target);
  }
}

其次,我们定义勇士类。勇士有一个Attack()方法,用来攻击敌人。

public class Samurai
{
    readonly Sword sword;
    public Samurai()
    {
        this.sword = new Sword();
    }
    
    public void Attack(string target)
    {
        this.sword.Hit(target);
    }
}

现在我们就可以创建一个勇士来战斗。

var warrior = new Samurai();
warrior.Attack("the evildoers");

我们运行这个程序就会打印出 Chopped the evildoers clean in half
现在引出我们的问题:如果我们想要给Samurai 装备不同的武器呢?
由于 Sword 是在 Samurai 类的构造函数中创建的,必须要改 Samurai才行。
很显然 Samurai 和 Sword 的耦合性太高了,我们先定义一个接口来解耦。

第一轮重构

首先需要建立松耦合组件:通过引入IWeapon,保证了与Sword之间没有直接的依赖项。

    public interface IWeapon
    {
        /// <summary>
        /// 击打目标
        /// </summary>
        /// <param name="target">目标</param>
        string Hit(string target);
    }

修改 Sword 类

    public class Sword : IWeapon
    {
        public string Hit(string target)
        {
            // 将目标切成两半
           return string.Format("Chopped {0} clean in half", target);
        }
    }

修改 Samurai 类,将原来构造函数中的Sword 移到构造函数的参数上,以接口来代替 , 然后我们就可以通过 Samurai 的构造函数来注入 Sword ,这就是一个DI的例子(通过构造函数注入)。

    public class Samurai
    {
        readonly IWeapon weapon;
        public Samurai(IWeapon weapon)
        {
            this.weapon = weapon;
        }

        public string Attack(string target)
        {
           return this.weapon.Hit(target);
        }
    }

如果我们需要用其他武器就不需要修改Samurai了。我们再创建另外一种武器。

    public class Shuriken : IWeapon
    {
        public string Hit(string target)
        {
            // 刺穿目标的铠甲
            return string.Format("Pierced {0}'s armor", target);
        }
    }

现在我们可以创建装备不同武器的战士了

var warrior1 = new Samurai(new Shuriken());
var warrior2 = new Samurai(new Sword());
warrior1.Attack("the evildoers");
warrior2.Attack("the evildoers");

权责申明

作者:编程小纸条 出处: https://www.cnblogs.com/miro/category/620362.html

原文地址:https://www.cnblogs.com/qianj/p/12522307.html