本系列笔记来自Ninject官方网站:http://www.ninject.org/wiki.html
一,Ninject介绍
Ninject是一个.net平台的依赖注入框架,借助于Ninject,我们使我们的程序变得更易于维护和修改。
手动实现依赖入注
看一个例子,现在我们要做一个控制台项目,一个士兵对抗恐怖分子的游戏。我们首先构造一个武器——剑。
1 class Sword 2 { 3 public void Hit(string target) 4 { 5 Console.WriteLine("Chopped {0} clean in half",target); 6 } 7 }
然后我们再创建一个士兵类
1 class Samurai 2 { 3 readonly Sword sword; 4 public Samurai() 5 { 6 this.sword = new Sword(); 7 } 8 9 public void Attack(string targer) 10 { 11 this.sword.Hit(targer); 12 } 13 }
最后,在主程序中,让士兵去攻击他的敌人
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 var warrior = new Samurai(); 6 warrior.Attack("the evildoers"); 7 8 Console.Read(); 9 } 10 }
运行程序,我们得到的结果是:
Chopped the evildoers clean in half
现在的问题是,我们剑对我们的士兵来说攻击力太低,我们想换成武士刀,怎么办呢。
当然可以再新建一个武士刀类,然后在Samurai类中把Sword换成武士刀。可这样做的并没有将Samurai和武士刀类分开,而是耦合在了一起,这样如果以后我们想把武士刀换成手*枪,就还需要再次更改Samurai类,这与程序设计中的“对添加开发,对修改封闭”的思想相悖。依赖入注的思想就是要将程序设计成高内聚,低耦合的特性。借助于接口,我们可以实现我们的目的。
创建IWeapon接口:
1 interface IWeapon 2 { 3 public void Hit(string target); 4 }
创建武士刀类并让它实现IWeapon接口:
1 class Shuriken:IWeapon 2 { 3 public void Hit(string target) 4 { 5 Console.WriteLine("Pierced {0}'s armor", target); 6 } 7 }
同样的让Sword类实现IWeapon接口:
1 class Sword:IWeapon 2 { 3 public void Hit(string target) 4 { 5 Console.WriteLine("Chopped {0} clean in half",target); 6 } 7 }
在士兵类内部,我们不在具体到是哪个具体的武器,而是武器这个接口:
1 class Samurai 2 { 3 readonly IWeapon weapon; 4 public Samurai() 5 { 6 this.weapon = new Sword(); 7 } 8 9 public void Attack(string targer) 10 { 11 this.weapon.Hit(targer); 12 } 13 }
但上面的代码并没有做到完全解耦的目的,因为其中还是关联了Sword这个类,我们可以把指定哪个类放到构造函数中并以接口代替,这样就做做到了跟具体的武器类完全解耦的目的。
1 class Samurai 2 { 3 readonly IWeapon weapon; 4 public Samurai(IWeapon weapon) 5 { 6 this.weapon = weapon; 7 } 8 9 public void Attack(string targer) 10 { 11 this.weapon.Hit(targer); 12 } 13 }
主程序中:
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 var warrior = new Samurai(new Sword()); 6 var warrior2 = new Samurai(new Shuriken()); 7 warrior.Attack("the evildoers"); 8 warrior2.Attack("the evildoers"); 9 10 Console.Read(); 11 } 12 }
这样我们就可以将具体武器的构造拿到主程序中来,而与士兵类和武器类完全分开,后续想要加手*枪类只需创建一个手*枪类并实现IWeapon类,就可以在主程序中随意创建装备了手*枪的士兵了。
这就是手动实现依赖入注的过程,在小项目中这样做是没有任何问题的,但当项目一旦大起来,这样做就可能很不合适了,要写于是就出现了类似Ninject这样的Ioc框架。