您好,登錄后才能下訂單哦!
ASP.NET MVC學前篇之Ninject的初步了解
廢話幾句,Ninject是一種輕量級的、基礎.NET的一個開源IoC框架,在對于MVC框架的學習中會用到IoC框架的,因為這種IoC開源框架有很多,本篇的主題只有一個,就是讓閱讀過本篇幅的朋友逗知道IoC框架在項目中的作用,以及它的重要性。 這樣做的目的是以便在以后的學習工作中選擇自己中意的一個IoC框架來學習、使用,或者是自己去實現一個。好了,不廢話了。
1.新建個4.0Framework的一個控制臺應用程序項目,名稱為IoCDemo
2.在http://www.ninject.org/download網頁中,下載Version 2.2版本的Ninject程序集(之前版本的不支持4.0庫),下載完成解壓后會看到如圖1里的幾個文件,在這里你只需要關心名稱為Ninject的文件,其它的忽略掉。
圖1
3.在項目中新建個Lib文件夾,并把Ninject.dll、Ninject.pdb和Ninject.xml三個文件拷貝到文件目錄下,并且添加引用到項目中。如圖2:
圖2
環境準備工作做好了,可以安心的來看示例了。捎帶一句Ninject.xml文件是程序集文件的注釋,不過都是英文的,對于姿勢水平不高的屌絲來說這并不算是福利,當然也包括本人。(ps:谷歌翻譯什么的很好用)
從上一篇的文章中,可以了解到一個基礎的IoC,這是站在容器對象的角度去考慮的,具體實現對象確實是可以動態的注入到容器對象中的。我們再看一下新的示例,并從中找到上一篇不足的地方,換個角度去看問題。
我們先定義了一個商品類,內容只包含了商品的編號、名稱和價格三個屬性
代碼3-1
1 /// <summary> 2 /// 貨品 3 /// </summary> 4 public class Commodity 5 { 6 public string CommodityID { get; set; } 7 public string Name { get; set; } 8 public float Price { get; set; } 9 }
商品類型定義好了之后,我們再定義個貨品的計價規范和它的一個基礎實現
代碼3-2
1 /// <summary> 2 /// 貨品計價規范 3 /// </summary> 4 public interface IValuation 5 { 6 float CommodityValuation(params Commodity[] commodities); 7 } 8 9 /// <summary> 10 /// 貨品計價規范實現一:商品價格合計 11 /// </summary> 12 public class CommoditySumValuation : IValuation 13 { 14 public float CommodityValuation(params Commodity[] commodities) 15 { 16 return commodities.Sum(commodity => commodity.Price); 17 } 18 }
這樣看來架勢和上一篇的相同,前段的確實是差不多的,不要著急慢慢來看。再定義個容器對象,并且通過構造注入的方式來實現解耦,讓容器對象和具體實現徹底的分離了。
代碼3-3
1 /// <summary> 2 /// 購物車-容器對象 3 /// </summary> 4 public class ShoppingCart 5 { 6 private IValuation _Valuation; 7 public ShoppingCart(IValuation valuation) 8 { 9 _Valuation = valuation; 10 } 11 12 public float CommodityTotalPrice() 13 { 14 Commodity[] commodities = 15 { 16 new Commodity(){ CommodityID="A1", Price=14}, 17 new Commodity(){ CommodityID="A2", Price=76.5f}, 18 new Commodity(){ CommodityID="B2", Price=34.4f}, 19 new Commodity(){ CommodityID="C4", Price=23.1f} 20 }; 21 22 return _Valuation.CommodityValuation(commodities); 23 } 24 }
對于上面那句話的定義,站在不同角度定義結果是不同的,如果站在容器對象的角度來看,確實是實現了解耦,如圖3
圖3
從圖中可以明確的看到ShoppingCart類型(容器)和CommoditySumValuation類型(具體實現)沒有任何的關系,從而以達到解耦的目的,但是問題要結合到實際從客戶端調用容器對象來看:
代碼3-4
1 namespace IoCDemo 2 { 3 class Program 4 { 5 static void Main(string[] args) 6 { 7 ShoppingCart shoppingCart = new ShoppingCart(new CommoditySumValuation()); 8 9 } 10 } 11 }
代碼看到這里,想必大家都會頭疼了,這整的叫什么事,饒了一圈還是耦合了。如圖4
圖4
這種情況下IoC框架就可以派上用場了,本篇介紹的是Ninject,那當然是用Ninject了,根據前面的環境配置,
代碼3-5
1 using Ninject; 2 3 namespace IoCDemo 4 { 5 class Program 6 { 7 static void Main(string[] args) 8 { 9 #region IoC框架功能 10 IKernel kernel = new StandardKernel(); 11 kernel.Bind<IValuation>().To<CommoditySumValuation>(); 12 IValuation valuation = kernel.Get<IValuation>(); 13 #endregion 14 15 ShoppingCart shoppingCart = new ShoppingCart(valuation); 16 Console.WriteLine(shoppingCart.CommodityTotalPrice().ToString()); 17 Console.ReadLine(); 18 } 19 } 20 }
這里是通過Ninject中的IKernel類型的Bind泛型方法來綁定IValuation類型,用To泛型方法中的類型表示是Bind方法中類型的實現,這樣在kernel.Get<IValuation>()的時候是返回的CommoditySumValuation類型。這里對Ninject的使用并不多做介紹,而是側重的解釋IoC的重要性及其作用。
這個時候的依賴結構如下圖5
圖5
這樣可能看不出IoC的效果,我們再新增一些需求,并且更改CommoditySumValuation實現類,
代碼3-6
1 /// <summary> 2 /// 計價折扣算法規范 3 /// </summary> 4 public interface IValuationDisCount 5 { 6 float ValuationDisCount(float listPrice); 7 } 8 9 /// <summary> 10 /// 計價折扣算法規范實現一:九折 走起 11 /// </summary> 12 public class DisCount : IValuationDisCount 13 { 14 15 public float ValuationDisCount(float listPrice) 16 { 17 return listPrice - (listPrice * 10 / 100); 18 } 19 }
添加了一個新需求規范和一個新的實現類,這樣可以給商品總和來打折了,還需在CommoditySumValuation實現類中實現構造注入,修改代碼如下:
代碼3-7
1 /// <summary> 2 /// 貨品計價規范實現一:商品價格合計 3 /// </summary> 4 public class CommoditySumValuation : IValuation 5 { 6 private IValuationDisCount valuationDisCount; 7 8 public CommoditySumValuation(IValuationDisCount valuationdiscount) 9 { 10 this.valuationDisCount = valuationdiscount; 11 } 12 13 public float CommodityValuation(params Commodity[] commodities) 14 { 15 return valuationDisCount.ValuationDisCount(commodities.Sum(commodity => commodity.Price)); 16 } 17 }
這個時候如果沒有IoC框架的存在,看下客戶端是怎么來調用的:
代碼3-8
1 using Ninject; 2 3 namespace IoCDemo 4 { 5 class Program 6 { 7 static void Main(string[] args) 8 { 9 ShoppingCart shoppingCart = 10 new ShoppingCart(new CommoditySumValuation(new DisCount())); 11 12 Console.WriteLine(shoppingCart.CommodityTotalPrice().ToString()); 13 Console.ReadLine(); 14 } 15 } 16 }
運行一下同樣也能得到結果,但是不管怎么的去抽象,在客戶端調用都需要直接依賴于實現類,而不是高層次的抽象,
圖7
從圖中可以看出來這是多么的恐怖。重新的修改下Main函數里的代碼把IoC框架給使用起來。
代碼3-9
1 using Ninject; 2 3 namespace IoCDemo 4 { 5 class Program 6 { 7 static void Main(string[] args) 8 { 9 #region IoC框架功能 10 IKernel kernel = new StandardKernel(); 11 kernel.Bind<IValuation>().To<CommoditySumValuation>(); 12 kernel.Bind<IValuationDisCount>().To<DisCount>(); 13 IValuation valuation = kernel.Get<IValuation>(); 14 #endregion 15 16 ShoppingCart shoppingCart = new ShoppingCart(valuation); 17 18 Console.WriteLine(shoppingCart.CommodityTotalPrice().ToString()); 19 Console.ReadLine(); 20 } 21 } 22 }
結果如圖8:
圖8
再來看一下依賴結構,
圖9
Ninject框架會檢查要返回的類型所依賴的所有類型,并且也會動態的注入到類型當中。
從圖7和圖9的對比中可以看出,只有通過增加IoC框架來進行客戶端和具體實現的解耦,沒有這個中間層的加入還真的不好來實現消除耦合,并且IoC框架還可以進行動態配置。
本篇到這里結束了,對Ninject感興趣的朋友請自行學習吧。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。