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

3.在项目中新建个Lib文件夹,并把Ninject.dll、Ninject.pdb和Ninject.xml三个文件拷贝到文件目录下,并且添加引用到项目中。如图2:

图2

环境准备工作做好了,可以安心的来看示例了。捎带一句Ninject.xml文件是程序集文件的注释,不过都是英文的,对于姿势水平不高的屌丝来说这并不算是福利,当然也包括本人。(ps:谷歌翻译什么的很好用)

3.初步认识、了解

从上一篇的文章中,可以了解到一个基础的IoC,这是站在容器对象的角度去考虑的,具体实现对象确实是可以动态的注入到容器对象中的。我们再看一下新的示例,并从中找到上一篇不足的地方,换个角度去看问题。

我们先定义了一个商品类,内容只包含了商品的编号、名称和价格三个属性

代码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 { getset; }
7         public string Name { getset; }
8         public float Price { getset; }
9     }

商品类型定义好了之后,我们再定义个货品的计价规范和它的一个基础实现

代码3-2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 1     /// <summary>
 2     /// 货品计价规范
 3     /// </summary>
 4     public interface IValuation
 5     {
 6         float CommodityValuation(params Commodity[] commodities);
 7     }
 
 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
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     }

对于上面那句话的定义,站在不同角度定义结果是不同的,如果站在容器对象的角度来看,确实是实现了解耦,如图3

图3

从图中可以明确的看到ShoppingCart类型(容器)和CommoditySumValuation类型(具体实现)没有任何的关系,从而以达到解耦的目的,但是问题要结合到实际从客户端调用容器对象来看:

代码3-4

1
2
3
4
5
6
7
8
9
10
11
 namespace IoCDemo
 2 {
 3     class Program
 4     {
 5         static void Main(string[] args)
 6         {
 7             ShoppingCart shoppingCart = new ShoppingCart(new CommoditySumValuation());
 
 9         }
10     }
11 }

代码看到这里,想必大家都会头疼了,这整的叫什么事,饶了一圈还是耦合了。如图4

图4

这种情况下IoC框架就可以派上用场了,本篇介绍的是Ninject,那当然是用Ninject了,根据前面的环境配置,

代码3-5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 using Ninject;
 
 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 1     /// <summary>
 2     /// 计价折扣算法规范
 3     /// </summary>
 4     public interface IValuationDisCount
 5     {
 6         float ValuationDisCount(float listPrice);
 7     }
 
 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 1     /// <summary>
 2     /// 货品计价规范实现一:商品价格合计
 3     /// </summary>
 4     public class CommoditySumValuation : IValuation
 5     {
 6         private IValuationDisCount valuationDisCount;
 
 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 using Ninject;
 
 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 using Ninject;
 
 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感兴趣的朋友请自行学习吧。

本文转自jinyuan0829 51CTO博客,原文链接:http://blog.51cto.com/jinyuan/1423570,如需转载请自行联系原作者

ASP.NET MVC学前篇之Ninject的初步了解相关推荐

  1. ASP.NET MVC 随笔汇总

    ASP.NET MVC 随笔汇总 为了方便大家浏览所以整理一下,有的系列篇幅中不是很全面以后会慢慢的补全的. 学前篇之: ASP.NET MVC学前篇之扩展方法.链式编程 ASP.NET MVC学前篇 ...

  2. ASP.NET MVC 控制器激活(二)

    ASP.NET MVC 控制器激活(二) 前言 在之前的篇幅中,用文字和图像来表示了控制器的激活过程,描述的角度都是从框架默认实现的角度去进行描述的,这样也使得大家都可以清楚的知道激活的过程以及其中涉 ...

  3. 跟我学ASP.NET MVC之五:SportsStrore开始

    跟我学ASP.NET MVC之五:SportsStrore开始 摘要: 这篇文章将介绍一个ASP.NET应用程序SportsStore的开发过程. 开始 创建解决方案 创建工程 在New ASP.NE ...

  4. ASP.NET MVC资源汇总(本文不断更新)

    本人的开发实践标明,即使是编写一个极小的永远不可能成长成大中型程序的程序,也应该使用MVC(或其他任何类似技术),因为这样才能保证有一天有能力去开发大中型程序.所以刚刚从C++转向ASP.net的时候 ...

  5. [ASP.NET MVC 小牛之路]04 - 依赖注入(DI)和Ninject

    特别提醒:本文编写时间是 2013 年,请根据目前 .NET 发展接收你所需的知识点. 为什么需要依赖注入 在[ASP.NET MVC 小牛之路]系列的理解MVC模式文章中,我们提到MVC的一个重要特 ...

  6. 艾伟_转载:学习 ASP.NET MVC (第五回)理论篇

    本系列文章导航 学习 ASP.NET MVC (第一回)理论篇 学习 ASP.NET MVC (第二回)实战篇 学习 ASP.NET MVC (第三回)实战篇 学习 ASP.NET MVC (第四回) ...

  7. apache2.4.9 开启path_info访问_【第一篇】ASP.NET MVC快速入门之数据库操作(MVC5+EF6)...

    新建项目 打开VS2015,找到菜单项[文件->新建->项目],打开向导对话框: 注意我们的选择项: 运行平台:.NET FrameWork 4.5 项目模板:ASP.NET Web Ap ...

  8. Asp.net MVC 示例项目Suteki.Shop分析之---结束篇

    到今天,这个系列的文章就要先告一段落了.其中我用了10篇文章也没有穷尽该项目的设计思想,只能从中捡了一些我感兴趣的东西进行了分析和说明,正所谓兴趣是最大的动力.当然限于本人水平有限,难免有一些认识上的 ...

  9. ASP.NET MVC的View是如何呈现出来的[实例篇]

    在<[设计篇]>篇中我们通过对View引擎的总体介绍讲述了从ViewResult的创建到View呈现的原理,为了让读者对View引擎及其View呈现机制具有一个深刻的认识,我们自定义一个简 ...

最新文章

  1. 在bootstrap ace样式框架上修改的后台管理型模板(Tab页后台管理模板)
  2. iOS底层(三)-状态寄存器
  3. javascript之变量,作用域和内存问题
  4. 【斩获7枚offer,入职阿里平台事业部】横扫阿里、美团、京东、 去哪儿之后,写下了这篇面经!
  5. JAVA中线程同步的方法
  6. 机器学习速成课程 | 练习 | Google Development——编程练习:提高神经网络的性能
  7. oracle查询相同想,返回相同总和的查询-Oracle SQL
  8. Python 带界面的可执行程序
  9. java的程序编码,JAVA编码转换的详细过程
  10. 7月最强书单丨博文视点新品畅销TOP10,让技术带你燃爆整个7月
  11. 记一次失败的电话面试
  12. [转贴]彻底解决 CrystalReports 登录失败问题。
  13. 服务器未能识别 HTTP 标头 SOAPAction 的值
  14. 如何卸载赛门铁克symantec,ivanti
  15. 网络七层模型及各层协议
  16. css背景颜色渐变 从左到右 从下到上
  17. 做了一个iGoogle新闻Gardget
  18. orc识别 语音识别 云真机 内网穿透快速调研
  19. 抓取特定路径下文件 可批量压缩成压缩包 并分享到微信
  20. 程序复杂性度量方法-McCabe

热门文章

  1. 电脑硬盘是干什么用的_电脑硬盘位不够用?有了它就不担心、奥睿科硬盘柜体验...
  2. php控制器面向对象编程,php面向对象编程
  3. 计算机缺乏内存将无法运行,电脑增加内存为什么无法启动
  4. oracle 分列,SQL 问题 如何分列
  5. 一梦江湖卡在获取服务器信息,一梦江湖小技巧,不氪金,卡级玩家怎么获取资源提升修为...
  6. 区块链 java 开源_详细介绍Java区块链开源代码背后的内容
  7. VPS批量管理软件--远程桌面批量管理
  8. Python3基础-分数运算
  9. python全栈-Day 14
  10. leetcode 反转字符串