1. 程式人生 > >ASP.NET MVC使用Ninject

ASP.NET MVC使用Ninject

      Ninject是一個快如閃電的,輕量級的。。。。。依賴注入框架,呃呃呃,貌似很少用到,Ninject就是一個DI容器,作用是對ASP.NET MVC程式中的元件進行解耦 ,說到解耦其實也有其他的方式可以達到解耦這個目的,比如介面

 1 public interface ITest
 2 {
 3     Decimal ValueProducts(IEnumerable<Product>products)  ;
 4 }
 5 public class Test:ITest
 6 {
 7     public Decimal ValueProducts(IEnumerable<Product>products)  
8 { 9 return products.sum(p=>p.Price); 10 } 11 } 12 public class ShoppingCart 13 { 14 private ITest test; 15 public IEnumerable<Product>products{set;get;} 16 public ShoppingCart( ITest test) 17 { 18 this.test=test; 19 } 20 public Decimal result(products);
21 }
View Vode

     通過介面可以說達到了我們想要的結果,也就是Shopping和Test之間的耦合。但是在控制器中卻沒辦法達到這個目的

public ActionResult Index(){
   ITest IT=new Test();
   ShoppingCart cart=new ShoppingCart(IT);{Products=products};
   Decimal total=IT.result();
   return View(total);
}

我們只能藉助Ninject來幫我們實現

可以通過nuget下載Ninect也可以通過Ninject下載

那麼我們該怎麼使用Ninject幫我們解決上述的問題呢?

其實使用Ninect不難,一共三個步驟:

//在控制器
public ActionResult Index()
{
    1:建立一個Ninject的核心
     IKernel ninject=new StandardKernel();
    2:就是配置Ninject核心,其實就是將實現類和介面類繫結在一起
    ninject.Bind<ITest>().To<Test>();
    3:最後一步就是使用Ninject建立一個物件了
    ITest IT=ninject.Get<ITest>();
}

從建立核心到建立物件跟Spring.Net倒是很相似。

可能有點點強迫症吧,覺得這麼一坨東西放在那裡好礙眼吖,不可能叫我每一個動作裡面都寫這一坨東西吧,當然不是。

下面就建立一個依賴項解析器(好像很高大上一樣,其實就是將上面的程式碼做個封裝而已)

public class NinjectResolver:IDependencyResolver
{
   private IKernel kernel;
   public  NinjectResolver(IKernel kernel)
   {
      this.kernel=kernel;      
      AddBinding();
   }
    public IEnumerable<Object> GetServices(Type serviceType)
   {
      return kernel.GetAll(serviceType);
    }
    public Object GetService(Type serviceType)
   {
       return kernel.TryGet(serviceType);
    }    
   void AddBinding()
   {
      kernel.Bind<ITest>().To<Test>();
    }
}   
IDependencyResolver這個是System.Mvc裡面的繼承這個介面必須實現GetServices和GetService,AddBinding這個方法是用來繫結實現類和介面

GetService方法中的TryGet類似於上面的Get,當沒有合適的繫結時,這個會返回一個null值,不會拋異常,而GetServices方法中的GetAll對單一型別的多個繫結時,可以用到這個
最後一步就是在App_Start這一個資料夾中找到NinjectWebCommon.cs這個檔案再找到 RegisterServices(IKernel kernel)這個方法新增
 System.Web.Mvc.DependencyResolver.SetResolver(newNinjectResolver(kernel));
這時候我們修改下控制器中的程式碼
private ITest test;
public HomeController(ITest test)
{
    this.test=test;
}
public ActionResult Index(){
   ShoppingCart cart=new ShoppingCart(IT);{Products=products};
   Decimal total=IT.result();  
return View(total); }
Ninject大概的用法也差不多了,下面說的時Ninject比較新穎的東西
就是指定屬性或者建構函式傳值了,其實也沒什麼,只是WithConstructorArgument和WithPropertyValue這兩個的使用
 public interface IHelper
 {
        Decimal ApplyDiscount(Decimal totalParam);        
 }
 public class Helper : IHelper
 {
        public Decimal DiscountSize { set; get; }       
     
        public decimal ApplyDiscount(decimal totalParam)
        {
            return (totalParam - (discountparam / 100m * totalParam));
        }
 }
private void AddBindings()
        {
            kernel.Bind<ITest>().To<Test>();
        
            kernel.Bind<IHelper>().To<Helper>().WithPropertyValue("DiscountSize", 50M);
 kernel.Bind<IHelper>().To<Helper>().WithConstructorArgument("discountparam", 50M);
}
WithPropertyValue這個有兩個引數一個是屬性名,一個是屬性值,這樣子可以一開始就給這個屬性賦值上預設值,個人感覺作用倒是不大,也有其他的方法可以實現同樣效果
WithConstructorArgument這個也差不多,引數一是建構函式的形參,後面的引數是值
好了,Ninject就介紹到這了,如有不對,請多多包涵