如果大家研究一些开源项目,会发现无处不在的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