Ninject 依賴注入
依賴性解析器用於避免緊密耦合的類,提高靈活性並使測試變得容易。你可以建立自己的依賴注入器(不推薦)或使用編寫良好且經過測試的依賴注入器之一。在這個例子中,我將使用 Ninject 。
第一步:建立依賴解析器
首先,從 NuGet 下載 Ninject 。建立名為 Infrastructure 的資料夾並新增名為 NinjectDependencyResolver 的類 :
using Ninject;
using System;
using System.Collections.Generic;
using System.Web.Mvc;
public class NinjectDependencyResolver
: IDependencyResolver
{
private IKernel kernel;
public NinjectDependencyResolver()
{
// Initialize kernel and add bindings
kernel = new StandardKernel();
AddBindings();
}
public object GetService(Type serviceType)
{
return kernel.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return kernel.GetAll(serviceType);
}
private void AddBindings()
{
// Bindings added here
}
}
當 MVC 框架需要一個類的 insance 來為傳入的請求提供服務時,它將呼叫 GetService 和 GetServices 方法。
第二步:註冊依賴解析器
現在我們有自定義依賴項解析器,我們需要註冊它以告訴 MVC 框架使用我們的依賴項解析器。在 Global.asax.cs 檔案中註冊依賴項解析器 :
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
DependencyResolver.SetResolver(new NinjectDependencyResolver());
// .....
}
第三步:新增繫結
想象一下,我們有以下介面和實現:
public interface ICustomCache
{
string Info { get; }
}
public class CustomCache : ICustomCache
{
public string Info
{
get
{
return "Hello from CustomCache.";
}
}
}
如果我們想在我們的控制器中使用 CustomCache 而不將我們的控制器與 CustomCache 緊密耦合,那麼我們需要將 ICustomCache 繫結到 CustomCache 並使用 Ninject 注入它。第一件事首先,結合 ICustomCache 到 CustomCache 通過新增以下程式碼來 AddBindings()
的方法 NinjectDependencyResolver :
private void AddBindings()
{
// Bindings added here
kernel.Bind<ICustomCache>().To<CustomCache>();
}
然後準備你的注射控制器,如下所示:
public class HomeController : Controller
{
private ICustomCache CustomCache { get; set; }
public HomeController(ICustomCache customCacheParam)
{
if (customCacheParam == null)
throw new ArgumentNullException(nameof(customCacheParam));
CustomCache = customCacheParam;
}
public ActionResult Index()
{
// cacheInfo: "Hello from CustomCache."
string cacheInfo = CustomCache.Info;
return View();
}
}
這是建構函式注入的示例,它是依賴注入的一種形式。如你所見,我們的 Home 控制器不依賴於 CustomCache 類 itslef。如果我們想在我們的應用程式中使用另一個 ICustomCache,我們唯一需要改變的是將 ICustomCache 繫結到另一個實現,這是我們需要採取的唯一步驟。這裡發生的事情是,MVC 框架要求我們註冊的依賴項解析器通過 GetService 方法建立 HomeController 類的例項。GetService 方法請求 Ninject 核心建立請求的物件,Ninject 核心檢查其術語中的型別,並發現 HomeController 的建構函式重新獲取 ** ICustomCache 並結合已新增 ICustomCache 。Ninject 建立繫結類的例項,使用它建立 HomeController 並返回它 MVC Framework。
依賴鏈
當 Ninject 嘗試建立型別時,它會檢查型別和其他型別之間的其他依賴關係,如果有任何 Ninject 也嘗試建立它們。例如,如果我們的 CustomCache 類需要 ICacheKeyProvider,並且如果為 ICacheKeyProvider 新增了 bining,Ninject 可以為我們的類提供它。
ICacheKeyProvider 介面和 SimpleCacheKeyProvider 實現:
public interface ICacheKeyProvider
{
string GenerateKey(Type type);
}
public class SimpleCacheKeyProvider
: ICacheKeyProvider
{
public string GenerateKey(Type type)
{
if (type == null)
throw new ArgumentNullException(nameof(type));
return string.Format("{0}CacheKey", type.Name);
}
}
修改了 CustomCache 類
public class CustomCache : ICustomCache
{
private ICacheKeyProvider CacheKeyProvider { get; set; }
public CustomCache(ICacheKeyProvider keyProviderParam)
{
if (keyProviderParam == null)
throw new ArgumentNullException(nameof(keyProviderParam));
CacheKeyProvider = keyProviderParam;
}
...........
}
為 ICacheKeyProvider 新增繫結 :
private void AddBindings()
{
// Bindings added here
kernel.Bind<ICustomCache>().To<CustomCache>();
kernel.Bind<ICacheKeyProvider>().To<SimpleCacheKeyProvider>();
}
現在,當我們導航到 HomeController 時, Ninject 會建立 SimpleCacheKeyProvider 的例項,使用它來建立 CustomCache 並使用 CustomCache 例項來建立 HomeController 。
Ninject 有很多很棒的功能,如連結依賴注入,如果你想使用 Ninject,你應該檢查它們。