Ninject依賴注入——建構函式、屬性、方法和欄位的注入(三)
1、Ninject簡介
Ninject是基於.Net平臺的依賴注入框架,它能夠將應用程式分離成一個個高內聚、低耦合(loosely-coupled, highly-cohesive)的模組,然後以一種靈活的方式組織起來。Ninject可以使程式碼變得更容易編寫、重用、測試和修改。
2、專案引用Ninject
1>、 Tools -> Libaary Package Manager -> Package Manager Console,開啟Package Manager Console視窗;
2>、在Package Manager Console視窗中輸入指令,Enter;
1 PM> Install-Package Ninject
3>、在專案中新增對Ninject的引用。
3、Ninject使用Modules and the Kernel注入
Ninject中將類別以模組(Module)形式進行分組繫結,每一個模組代表應用程式的一個獨立部分,這些模組可以根據需要進行組織。每一個模組都需要實現介面IModule,多數採用擴充套件StandardModule類來便捷實現。
Ninject依賴注入包括建構函式、屬性、方法和欄位的依賴注入。以下先通過建構函式注入方式進行說明,仍採用上節中使用的介面及類。
1>、Ninject建構函式依賴注入(Constructor Injection)
武器介面IWeapon(IWeapon.cs):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NInjectApp
{
/// <summary>
/// 武器
/// </summary>
public interface IWeapon
{
void Hit(string target);
}
}
武器類Sword(Sword.cs):勇士類Samurai(Samurai.cs),在建構函式Samurai中新增[Inject]屬性(Attribute)。using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace NInjectApp { /// <summary> /// 刀 /// </summary> public class Sword : IWeapon { public void Hit(string target) { Console.WriteLine("Hit the target {0} by sword", target); } } }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ninject;
namespace NInjectApp
{
/// <summary>
/// 勇士
/// </summary>
public class Samurai
{
private IWeapon _weapon;
[Inject]
public Samurai(IWeapon weapon)
{
_weapon = weapon;
}
public void Attack(string target)
{
_weapon.Hit(target);
}
}
}
新增勇士類別繫結模組類WarriorModule(WarriorModule.cs)。using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ninject.Modules;
namespace NInjectApp
{
public class WarriorModule : NinjectModule
{
public override void Load()
{
Bind<IWeapon>().To<Sword>();
Bind<Samurai>().ToSelf();
}
}
}
建立模組(Module)後,將它們載入到Kernel容器中。呼叫Kernel的Get()方法,獲取Ninject的類別例項。using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ninject;
namespace NInjectApp
{
class Program
{
static void Main(string[] args)
{
IKernel kernal = new StandardKernel(new WarriorModule());
//Samurai s = new Samurai(kernal.Get<IWeapon>()); // 建構函式注入
Samurai s = kernal.Get<Samurai>();
s.Attack("enemy");
Console.ReadKey();
}
}
}
如果需要的話,也可以建立多個模組(Module),將它們引數傳遞到Kernel的建構函式中。public class Module1 {
public override void Load() { ... }
}
public class Module2 {
public override void Load() { ... }
}
class Program {
public static void Main()
{
IKernel kernel = new StandardKernel(new Module1(), new Module2(), ...);
...
}
}
2>、Ninject屬性依賴注入(Property Injection)
與建構函式注入不同,可以有多個屬性(Property)宣告[Inject] Attribute。
修改Samurai類和Program類,其他不變。
Samurai類注入屬性:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ninject;
namespace NInjectApp
{
/// <summary>
/// 勇士
/// </summary>
public class Samurai
{
private IWeapon _weapon;
/// <summary>
/// 定義注入介面屬性
/// </summary>
[Inject]
public IWeapon Weapon
{
get
{
return _weapon;
}
set
{
_weapon = value;
}
}
public void Attack(string target)
{
_weapon.Hit(target);
}
}
}
Program類呼叫:using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ninject;
namespace NInjectApp
{
class Program
{
static void Main(string[] args)
{
IKernel kernal = new StandardKernel(new WarriorModule());
Samurai s = new Samurai() { Weapon = kernal.Get<IWeapon>() };// 屬性注入
s.Attack("enemy");
Console.ReadKey();
}
}
}
3>、Ninject方法注入(Method Injection)
Ninject可以有多個方法(Method)宣告[Inject]屬性(Attribute)。
修改Samurai類和Program類,其他不變。
Samurai類添加註入方法:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ninject;
namespace NInjectApp
{
/// <summary>
/// 勇士
/// </summary>
public class Samurai
{
private IWeapon _weapon;
[Inject]
public void Arm(IWeapon weapon)
{
_weapon = weapon;
}
public void Attack(string target)
{
_weapon.Hit(target);
}
}
}
Program類呼叫注入方法:using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ninject;
namespace NInjectApp
{
class Program
{
static void Main(string[] args)
{
IKernel kernal = new StandardKernel(new WarriorModule());
Samurai s = new Samurai();
s.Arm(kernal.Get<IWeapon>()); // 方法注入
s.Attack("enemy");
Console.ReadKey();
}
}
}
4>、Ninject欄位注入(Field Injection)
Ninject可以有多個欄位(Field)宣告[Inject]屬性(Attribute),但在實際應用中儘量避免使用欄位注入。
修改Samurai類和Program類,其他不變。
Samurai類添加註入欄位:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ninject;
namespace NInjectApp
{
/// <summary>
/// 勇士
/// </summary>
public class Samurai
{
[Inject]
private IWeapon _weapon;
public void Attack(string target)
{
_weapon.Hit(target);
}
}
}
Program類中呼叫注入欄位:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ninject;
namespace NInjectApp
{
class Program
{
static void Main(string[] args)
{
IKernel kernal = new StandardKernel(new WarriorModule());
Samurai s = new Samurai();
s._weapon = kernal.Get<IWeapon>(); // 需將Samurai類中欄位_weapon修飾符改為public才可以訪問
s.Attack("enemy");
Console.ReadKey();
}
}
}