qidao123.com技术社区-IT企服评测·应用市场
标题:
保举一款Ioc容器之Ninject入门详解
[打印本页]
作者:
瑞星
时间:
2025-4-8 17:58
标题:
保举一款Ioc容器之Ninject入门详解
随着软件的不断发展,功能越来越复杂,为了将复杂的逻辑简单化,解耦成了架构师,工程师们经常提起的话题,今天我们就以一个简单的小例子,来看一下解耦的好处,顺便介绍一款Ioc容器Ninject的应用,仅供学习分享利用,如有不足之处,还请指正。
假设场景
在武侠小说中,江湖代表着神秘莫测,身不由己,更有传奇色彩浓郁的江湖英雄榜,剑气纵横,枪出如龙,南帝北丐,东邪西毒,不可胜数。今天我们就以刀剑为例进行说明。
比如,有一个剑的类(Sword),它的主要攻击方式为劈,挑等招数,如下所示:
/// <summary>
/// 剑
/// </summary>
public class Sword
{
public void Hit(string target)
{
Console.WriteLine($"剑将 {target} 劈成两半.");
}
}
复制代码
有一个飞镖的类(Shuriken),它的主要攻击方式为长途飞刺,如下所示:
/// <summary>
/// 手里剑,飞镖
/// </summary>
public class Shuriken
{
public void Hit(string target)
{
Console.WriteLine("手里剑刺破 {0} 的盔甲", target);
}
}
复制代码
有一位少侠(Samurai),当他用剑时,他的武功招数以劈,挑为主,如下所示:
/// <summary>
/// 武士
/// </summary>
public class Samurai
{
readonly Sword sword;
public Samurai()
{
this.sword = new Sword();
}
/// <summary>
/// 攻击
/// </summary>
/// <param name="target"></param>
public void Attack(string target)
{
this.sword.Hit(target);
}
}
复制代码
在上述例子中,剑(Sword)做为兵器的一种,在少侠(Samurai)的构造函数中进行创建,并利用,这样少侠(Samurai)和剑(Sword)就形成了强耦合关系(少侠依靠于剑),假如少侠想利用暗器飞镖(Shuriken)作为武器,又该怎样呢?
为相识决这种依靠关系,我们为可以创建接口(interface)来做为剑(Sword)和飞镖(Shuriken)的声明,在这里,我们创建了一个武器接口(IWeapon),它具有攻击的功能(Hit),如下所示:
/// <summary>
/// 武器
/// </summary>
public interface IWeapon
{
/// <summary>
/// 攻击
/// </summary>
/// <param name="target"></param>
void Hit(string target);
}
复制代码
而剑(Sword)和飞镖(Shuriken)分别实现武器接口(IWeapon),如下所示:
剑(Sword)的实现类
public class Sword : IWeapon
{
public void Hit(string target)
{
Console.WriteLine("剑将 {0} 劈成两半", target);
}
}
复制代码
飞镖(Shuriken)的实现类
/// <summary>
/// 手里剑,飞镖
/// </summary>
public class Shuriken : IWeapon
{
public void Hit(string target)
{
Console.WriteLine("手里剑刺破 {0} 的盔甲", target);
}
}
复制代码
当抽象出来武器接口(IWeapon)后,这样的我们的少侠(Samurai)就可以依靠武器接口(IWeapon),而不是具体的实现剑(Sword)和飞镖(Shuriken),如下所示:
public class Samurai
{
readonly IWeapon weapon;
public Samurai(IWeapon weapon)
{
this.weapon = weapon;
}
public void Attack(string target)
{
this.weapon.Hit(target);
}
}
复制代码
当少侠(Samurai)想用剑(Sword)时,就传入剑的实现,想用飞镖(Shuriken)时,就传入飞镖的实现,如下所示:
class Program
{
public static void Main()
{
var warrior1 = new Samurai(new Shuriken());//飞镖少侠
var warrior2 = new Samurai(new Sword());//用剑少侠
warrior1.Attack("坏人");
warrior2.Attack("坏人");
}
}
复制代码
以上就是面向接口编程的根本实现,只是接纳手动的方式进行解耦(需要手动的创建对象),接下来我们将依靠Ioc容器进行主动创建解耦。
Ninject
首先安装Ninject库,在Visual Studio 2022中,可以通过Nuget包管理器进行安装,如下所示:
创建TestModule类,它继承自NinjectModule类,重写Load方法并在Load方法中,通过Bind绑定接口的实现,如下所示:
public class TestModule : NinjectModule
{
public override void Load()
{
Bind<IWeapon>().To<Sword>();
Bind<Samurai>().ToSelf().InSingletonScope();
}
}
复制代码
Ninject提供了一个IKernel接口,以及对接口的尺度实现(StandardKernel),在创建IKernel对象时,传递TestModule实例对象,这样就可以获取少侠(Samurai)实例对象,且主动识别依靠关系,并创建注入的IWeapon接口对象,如下所示:
class Program
{
public static void Main()
{
IKernel kernel = new StandardKernel(new TestModule());
Samurai warrior = kernel.Get<Samurai>();
warrior.Attack("坏人");
}
}
复制代码
在上述示例中,注入的兵器接口(IWeapon)的实现接口为剑(Sword),则少侠(Samurai)主动匹配剑的攻击方式,如下所示:
那么如果少侠(Samurai)在利用剑(Sword)的时候,又想利用飞镖(Shuriken),就是少侠(Samurai)想同时利用两种或多种兵器(IWeapon),这样才能让敌人防不胜防,我们该怎样做呢?
接下来,我们修改少侠类(Samurai),将依靠的IWeapon接口改为接口数组,在构造函数中传入IWeapon接口数组,如下所示:
public class Samurai
{
readonly IWeapon[] weapons;
public Samurai(IWeapon[] weapons)
{
this.weapons = weapons;
}
public void Attack(string target)
{
foreach (var weapon in weapons)
{
weapon.Hit(target);
}
}
}
复制代码
然后在TestModule类中注入兵器(IWeapon)的两个实现剑(Sword)和飞镖(Shuriken),如下所示:
public class TestModule : NinjectModule
{
public override void Load()
{
Bind<IWeapon>().To<Sword>();
Bind<IWeapon>().To<Shuriken>();
Bind<Samurai>().ToSelf().InSingletonScope();
}
}
复制代码
通过Ioc容器获取少侠(Samurai)实例的方式不变,运行程序,发现少侠(Samurai)在与对手比武时,同时利用了两种功法(Attack),如下所示:
参考文档
关于Ninject的应用还有很多,本文只是简略介绍,更多内容,可参考官方文档:https://github.com/ninject/Ninject/wiki
以上就是《保举一款Ioc容器之Ninject入门详解》的全部内容,旨在抛砖引玉,一起学习,共同进步
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 qidao123.com技术社区-IT企服评测·应用市场 (https://dis.qidao123.com/)
Powered by Discuz! X3.4