Ninject学习笔记三
ASP.NET MVC學(xué)前篇之Ninject的初步了解
1.介紹
廢話幾句,Ninject是一種輕量級(jí)的、基礎(chǔ).NET的一個(gè)開源IoC框架,在對(duì)于MVC框架的學(xué)習(xí)中會(huì)用到IoC框架的,因?yàn)檫@種IoC開源框架有很多,本篇的主題只有一個(gè),就是讓閱讀過(guò)本篇幅的朋友逗知道IoC框架在項(xiàng)目中的作用,以及它的重要性。 這樣做的目的是以便在以后的學(xué)習(xí)工作中選擇自己中意的一個(gè)IoC框架來(lái)學(xué)習(xí)、使用,或者是自己去實(shí)現(xiàn)一個(gè)。好了,不廢話了。
?
2.環(huán)境準(zhǔn)備
1.新建個(gè)4.0Framework的一個(gè)控制臺(tái)應(yīng)用程序項(xiàng)目,名稱為IoCDemo
2.在http://www.ninject.org/download網(wǎng)頁(yè)中,下載Version 2.2版本的Ninject程序集(之前版本的不支持4.0庫(kù)),下載完成解壓后會(huì)看到如圖1里的幾個(gè)文件,在這里你只需要關(guān)心名稱為Ninject的文件,其它的忽略掉。
圖1
?
3.在項(xiàng)目中新建個(gè)Lib文件夾,并把Ninject.dll、Ninject.pdb和Ninject.xml三個(gè)文件拷貝到文件目錄下,并且添加引用到項(xiàng)目中。如圖2:
圖2
環(huán)境準(zhǔn)備工作做好了,可以安心的來(lái)看示例了。捎帶一句Ninject.xml文件是程序集文件的注釋,不過(guò)都是英文的,對(duì)于姿勢(shì)水平不高的屌絲來(lái)說(shuō)這并不算是福利,當(dāng)然也包括本人。(ps:谷歌翻譯什么的很好用)
3.初步認(rèn)識(shí)、了解
從上一篇的文章中,可以了解到一個(gè)基礎(chǔ)的IoC,這是站在容器對(duì)象的角度去考慮的,具體實(shí)現(xiàn)對(duì)象確實(shí)是可以動(dòng)態(tài)的注入到容器對(duì)象中的。我們?cè)倏匆幌滦碌氖纠?#xff0c;并從中找到上一篇不足的地方,換個(gè)角度去看問題。
我們先定義了一個(gè)商品類,內(nèi)容只包含了商品的編號(hào)、名稱和價(jià)格三個(gè)屬性
代碼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 }商品類型定義好了之后,我們?cè)俣x個(gè)貨品的計(jì)價(jià)規(guī)范和它的一個(gè)基礎(chǔ)實(shí)現(xiàn)
代碼3-2
1 /// <summary>2 /// 貨品計(jì)價(jià)規(guī)范3 /// </summary>4 public interface IValuation5 {6 float CommodityValuation(params Commodity[] commodities);7 }8 9 /// <summary> 10 /// 貨品計(jì)價(jià)規(guī)范實(shí)現(xiàn)一:商品價(jià)格合計(jì) 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 }這樣看來(lái)架勢(shì)和上一篇的相同,前段的確實(shí)是差不多的,不要著急慢慢來(lái)看。再定義個(gè)容器對(duì)象,并且通過(guò)構(gòu)造注入的方式來(lái)實(shí)現(xiàn)解耦,讓容器對(duì)象和具體實(shí)現(xiàn)徹底的分離了。
代碼3-3
1 /// <summary>2 /// 購(gòu)物車-容器對(duì)象3 /// </summary>4 public class ShoppingCart5 {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 }對(duì)于上面那句話的定義,站在不同角度定義結(jié)果是不同的,如果站在容器對(duì)象的角度來(lái)看,確實(shí)是實(shí)現(xiàn)了解耦,如圖3
圖3
從圖中可以明確的看到ShoppingCart類型(容器)和CommoditySumValuation類型(具體實(shí)現(xiàn))沒有任何的關(guān)系,從而以達(dá)到解耦的目的,但是問題要結(jié)合到實(shí)際從客戶端調(diào)用容器對(duì)象來(lái)看:
代碼3-4
1 namespace IoCDemo2 {3 class Program4 {5 static void Main(string[] args)6 {7 ShoppingCart shoppingCart = new ShoppingCart(new CommoditySumValuation());8 9 } 10 } 11 }代碼看到這里,想必大家都會(huì)頭疼了,這整的叫什么事,饒了一圈還是耦合了。如圖4
圖4
這種情況下IoC框架就可以派上用場(chǎng)了,本篇介紹的是Ninject,那當(dāng)然是用Ninject了,根據(jù)前面的環(huán)境配置,
代碼3-5
1 using Ninject;2 3 namespace IoCDemo4 {5 class Program6 {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 }這里是通過(guò)Ninject中的IKernel類型的Bind泛型方法來(lái)綁定IValuation類型,用To泛型方法中的類型表示是Bind方法中類型的實(shí)現(xiàn),這樣在kernel.Get<IValuation>()的時(shí)候是返回的CommoditySumValuation類型。這里對(duì)Ninject的使用并不多做介紹,而是側(cè)重的解釋IoC的重要性及其作用。
這個(gè)時(shí)候的依賴結(jié)構(gòu)如下圖5
圖5
這樣可能看不出IoC的效果,我們?cè)傩略鲆恍┬枨?#xff0c;并且更改CommoditySumValuation實(shí)現(xiàn)類,
代碼3-6
1 /// <summary>2 /// 計(jì)價(jià)折扣算法規(guī)范3 /// </summary>4 public interface IValuationDisCount5 {6 float ValuationDisCount(float listPrice);7 }8 9 /// <summary> 10 /// 計(jì)價(jià)折扣算法規(guī)范實(shí)現(xiàn)一:九折 走起 11 /// </summary> 12 public class DisCount : IValuationDisCount 13 { 14 15 public float ValuationDisCount(float listPrice) 16 { 17 return listPrice - (listPrice * 10 / 100); 18 } 19 }添加了一個(gè)新需求規(guī)范和一個(gè)新的實(shí)現(xiàn)類,這樣可以給商品總和來(lái)打折了,還需在CommoditySumValuation實(shí)現(xiàn)類中實(shí)現(xiàn)構(gòu)造注入,修改代碼如下:
代碼3-7
1 /// <summary>2 /// 貨品計(jì)價(jià)規(guī)范實(shí)現(xiàn)一:商品價(jià)格合計(jì)3 /// </summary>4 public class CommoditySumValuation : IValuation5 {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 }這個(gè)時(shí)候如果沒有IoC框架的存在,看下客戶端是怎么來(lái)調(diào)用的:
代碼3-8
1 using Ninject;2 3 namespace IoCDemo4 {5 class Program6 {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 }運(yùn)行一下同樣也能得到結(jié)果,但是不管怎么的去抽象,在客戶端調(diào)用都需要直接依賴于實(shí)現(xiàn)類,而不是高層次的抽象,
圖7
從圖中可以看出來(lái)這是多么的恐怖。重新的修改下Main函數(shù)里的代碼把IoC框架給使用起來(lái)。
代碼3-9
1 using Ninject;2 3 namespace IoCDemo4 {5 class Program6 {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 }結(jié)果如圖8:
圖8
再來(lái)看一下依賴結(jié)構(gòu),
圖9
Ninject框架會(huì)檢查要返回的類型所依賴的所有類型,并且也會(huì)動(dòng)態(tài)的注入到類型當(dāng)中。
從圖7和圖9的對(duì)比中可以看出,只有通過(guò)增加IoC框架來(lái)進(jìn)行客戶端和具體實(shí)現(xiàn)的解耦,沒有這個(gè)中間層的加入還真的不好來(lái)實(shí)現(xiàn)消除耦合,并且IoC框架還可以進(jìn)行動(dòng)態(tài)配置。
本篇到這里結(jié)束了,對(duì)Ninject感興趣的朋友請(qǐng)自行學(xué)習(xí)吧。
?
?
作者:金源
出處:http://www.cnblogs.com/jin-yuan/
本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁(yè)面
總結(jié)
以上是生活随笔為你收集整理的Ninject学习笔记三的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为什么要用Hibernate框架? 把S
- 下一篇: 在Web中实现C/S模式的Tab