ASP.NET MVC学前篇之Ninject的初步了解
?ASP.NET MVC學(xué)前篇之Ninject的初步了解
1.介紹
廢話幾句,Ninject是一種輕量級的、基礎(chǔ).NET的一個開源IoC框架,在對于MVC框架的學(xué)習(xí)中會用到IoC框架的,因為這種IoC開源框架有很多,本篇的主題只有一個,就是讓閱讀過本篇幅的朋友逗知道IoC框架在項目中的作用,以及它的重要性。 這樣做的目的是以便在以后的學(xué)習(xí)工作中選擇自己中意的一個IoC框架來學(xué)習(xí)、使用,或者是自己去實現(xiàn)一個。好了,不廢話了。
?
2.環(huán)境準(zhǔn)備
1.新建個4.0Framework的一個控制臺應(yīng)用程序項目,名稱為IoCDemo
2.在http://www.ninject.org/download網(wǎng)頁中,下載Version 2.2版本的Ninject程序集(之前版本的不支持4.0庫),下載完成解壓后會看到如圖1里的幾個文件,在這里你只需要關(guān)心名稱為Ninject的文件,其它的忽略掉。
圖1
?
3.在項目中新建個Lib文件夾,并把Ninject.dll、Ninject.pdb和Ninject.xml三個文件拷貝到文件目錄下,并且添加引用到項目中。如圖2:
圖2
環(huán)境準(zhǔn)備工作做好了,可以安心的來看示例了。捎帶一句Ninject.xml文件是程序集文件的注釋,不過都是英文的,對于姿勢水平不高的屌絲來說這并不算是福利,當(dāng)然也包括本人。(ps:谷歌翻譯什么的很好用)
3.初步認(rèn)識、了解
從上一篇的文章中,可以了解到一個基礎(chǔ)的IoC,這是站在容器對象的角度去考慮的,具體實現(xiàn)對象確實是可以動態(tài)的注入到容器對象中的。我們再看一下新的示例,并從中找到上一篇不足的地方,換個角度去看問題。
我們先定義了一個商品類,內(nèi)容只包含了商品的編號、名稱和價格三個屬性
代碼3-1
| 1 2 3 4 5 6 7 8 9 | 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?????} |
商品類型定義好了之后,我們再定義個貨品的計價規(guī)范和它的一個基礎(chǔ)實現(xiàn)
代碼3-2
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | ?1?????///?<summary> ?2?????///?貨品計價規(guī)范 ?3?????///?</summary> ?4?????public?interface?IValuation ?5?????{ ?6?????????float?CommodityValuation(params?Commodity[]?commodities); ?7?????} ?8? ?9?????///?<summary> 10?????///?貨品計價規(guī)范實現(xiàn)一:商品價格合計 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?????} |
這樣看來架勢和上一篇的相同,前段的確實是差不多的,不要著急慢慢來看。再定義個容器對象,并且通過構(gòu)造注入的方式來實現(xiàn)解耦,讓容器對象和具體實現(xiàn)徹底的分離了。
代碼3-3
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ?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?????} |
對于上面那句話的定義,站在不同角度定義結(jié)果是不同的,如果站在容器對象的角度來看,確實是實現(xiàn)了解耦,如圖3
圖3
從圖中可以明確的看到ShoppingCart類型(容器)和CommoditySumValuation類型(具體實現(xiàn))沒有任何的關(guān)系,從而以達(dá)到解耦的目的,但是問題要結(jié)合到實際從客戶端調(diào)用容器對象來看:
代碼3-4
| 1 2 3 4 5 6 7 8 9 10 11 | ?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,那當(dāng)然是用Ninject了,根據(jù)前面的環(huán)境配置,
代碼3-5
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | ?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方法中類型的實現(xiàn),這樣在kernel.Get<IValuation>()的時候是返回的CommoditySumValuation類型。這里對Ninject的使用并不多做介紹,而是側(cè)重的解釋IoC的重要性及其作用。
這個時候的依賴結(jié)構(gòu)如下圖5
圖5
這樣可能看不出IoC的效果,我們再新增一些需求,并且更改CommoditySumValuation實現(xiàn)類,
代碼3-6
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | ?1?????///?<summary> ?2?????///?計價折扣算法規(guī)范 ?3?????///?</summary> ?4?????public?interface?IValuationDisCount ?5?????{ ?6?????????float?ValuationDisCount(float?listPrice); ?7?????} ?8? ?9?????///?<summary> 10?????///?計價折扣算法規(guī)范實現(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?????} |
添加了一個新需求規(guī)范和一個新的實現(xiàn)類,這樣可以給商品總和來打折了,還需在CommoditySumValuation實現(xiàn)類中實現(xiàn)構(gòu)造注入,修改代碼如下:
代碼3-7
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | ?1?????///?<summary> ?2?????///?貨品計價規(guī)范實現(xiàn)一:商品價格合計 ?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框架的存在,看下客戶端是怎么來調(diào)用的:
代碼3-8
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | ?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?} |
運行一下同樣也能得到結(jié)果,但是不管怎么的去抽象,在客戶端調(diào)用都需要直接依賴于實現(xiàn)類,而不是高層次的抽象,
圖7
從圖中可以看出來這是多么的恐怖。重新的修改下Main函數(shù)里的代碼把IoC框架給使用起來。
代碼3-9
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ?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?} |
結(jié)果如圖8:
圖8
再來看一下依賴結(jié)構(gòu),
圖9
Ninject框架會檢查要返回的類型所依賴的所有類型,并且也會動態(tài)的注入到類型當(dāng)中。
從圖7和圖9的對比中可以看出,只有通過增加IoC框架來進(jìn)行客戶端和具體實現(xiàn)的解耦,沒有這個中間層的加入還真的不好來實現(xiàn)消除耦合,并且IoC框架還可以進(jìn)行動態(tài)配置。
本篇到這里結(jié)束了,對Ninject感興趣的朋友請自行學(xué)習(xí)吧。
?
? ? ?本文轉(zhuǎn)自jinyuan0829 51CTO博客,原文鏈接:http://blog.51cto.com/jinyuan/1423570,如需轉(zhuǎn)載請自行聯(lián)系原作者
總結(jié)
以上是生活随笔為你收集整理的ASP.NET MVC学前篇之Ninject的初步了解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 你不知道的javascript事件
- 下一篇: CSS 详细解读定位属性 positio