ASP.NET MVC學前篇之Ninject的初步瞭解

來源:互聯網
上載者:User

標籤:ninject   ioc   依賴注入   

 ASP.NET MVC學前篇之Ninject的初步瞭解

1.介紹

廢話幾句,Ninject是一種輕量級的、基礎.NET的一個開源IoC架構,在對於MVC架構的學習中會用到IoC架構的,因為這種IoC開源架構有很多,本篇的主題只有一個,就是讓閱讀過本篇幅的朋友逗知道IoC架構在項目中的作用,以及它的重要性。 這樣做的目的是以便在以後的學習工作中選擇自己中意的一個IoC架構來學習、使用,或者是自己去實現一個。好了,不廢話了。

 

2.環境準備

1.建立個4.0Framework的一個控制台應用程式項目,名稱為IoCDemo

2.在http://www.ninject.org/download網頁中,下載Version 2.2版本的Ninject程式集(之前版本的不支援4.0庫),下載完成解壓後會看到1裡的幾個檔案,在這裡你只需要關心名稱為Ninject的檔案,其它的忽略掉。

圖1

 650) this.width=650;" src="http://images.cnitblog.com/i/627988/201406/022224256451966.png" />


3.在項目中建立個Lib檔案夾,並把Ninject.dll、Ninject.pdb和Ninject.xml三個檔案拷貝到檔案目錄下,並且添加引用到項目中。2:

圖2

650) this.width=650;" src="http://images.cnitblog.com/i/627988/201406/022225202706311.png" />

環境準備工作做好了,可以安心的來看樣本了。捎帶一句Ninject.xml檔案是組件檔的注釋,不過都是英文的,對於姿勢水平不高的屌絲來說這並不算是福利,當然也包括本人。(ps:Google翻譯什麼的很好用)

3.初步認識、瞭解

從上一篇的文章中,可以瞭解到一個基礎的IoC,這是站在容器物件的角度去考慮的,具體實現對象確實是可以動態注入到容器物件中的。我們再看一下新的樣本,並從中找到上一篇不足的地方,換個角度去看問題。

我們先定義了一個商品類,內容只包含了商品的編號、名稱和價格三個屬性

代碼3-1

1     /// <summary>2     /// 貨品3     /// </summary>4     public class Commodity5     {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 : IValuation13     {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

650) this.width=650;" style="width:730px;height:231px;" src="http://images.cnitblog.com/i/627988/201406/022229150363623.png" width="711" height="181" />

可以明確的看到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

650) this.width=650;" style="width:741px;height:266px;" src="http://images.cnitblog.com/i/627988/201406/022232463178508.png" width="825" height="229" />

這種情況下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             #endregion14 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

650) this.width=650;" style="width:738px;height:261px;" src="http://images.cnitblog.com/i/627988/201406/022234396928238.png" width="623" height="187" />

這樣可能看不出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 : IValuationDisCount13     {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

650) this.width=650;" style="width:738px;height:181px;" src="http://images.cnitblog.com/i/627988/201406/022238017551973.png" width="697" height="160" />

可以看出來這是多麼的恐怖。重新的修改下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             #endregion15 16             ShoppingCart shoppingCart = new ShoppingCart(valuation);17 18             Console.WriteLine(shoppingCart.CommodityTotalPrice().ToString());19             Console.ReadLine();20         }21     }22 }

結果8:

圖8

650) this.width=650;" src="http://images.cnitblog.com/i/627988/201406/022239150831306.png" />

再來看一下依賴結構,

圖9

650) this.width=650;" style="width:745px;height:213px;" src="http://images.cnitblog.com/i/627988/201406/022240407701827.png" width="756" height="213" />

Ninject架構會檢查要返回的類型所依賴的所有類型,並且也會動態注入到類型當中。
從圖7和圖9的對比中可以看出,只有通過增加IoC架構來進行用戶端和具體實現的解耦,沒有這個中介層的加入還真的不好來實現消除耦合,並且IoC架構還可以進行動態配置。
本篇到這裡結束了,對Ninject感興趣的朋友請自行學習吧。

 

本文出自 “金源” 部落格,請務必保留此出處http://jinyuan.blog.51cto.com/8854733/1423570

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.