博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ASP.NET MVC学前篇之Ninject的初步了解
阅读量:5989 次
发布时间:2019-06-20

本文共 5653 字,大约阅读时间需要 18 分钟。

 ASP.NET MVC学前篇之Ninject的初步了解

1.介绍

废话几句,Ninject是一种轻量级的、基础.NET的一个开源IoC框架,在对于MVC框架的学习中会用到IoC框架的,因为这种IoC开源框架有很多,本篇的主题只有一个,就是让阅读过本篇幅的朋友逗知道IoC框架在项目中的作用,以及它的重要性。 这样做的目的是以便在以后的学习工作中选择自己中意的一个IoC框架来学习、使用,或者是自己去实现一个。好了,不废话了。

 

2.环境准备

1.新建个4.0Framework的一个控制台应用程序项目,名称为IoCDemo

2.在网页中,下载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 { 
get
set
; }
7         
public 
string 
Name { 
get
set
; }
8         
public 
float 
Price { 
get
set
; }
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,如需转载请自行联系原作者

你可能感兴趣的文章
灰度图像亮度对比度调整的简单代码
查看>>
iPhone5终于出现了
查看>>
15.scrapy中selenium的应用
查看>>
需求工程-软件建模与分析读书笔记1
查看>>
c#学习笔记 WPF中绘制各种数学图形
查看>>
数值积分中的梯形法则
查看>>
《陶哲轩实分析》习题10.4.1
查看>>
【云图】自有数据的多边形检索(云检索)
查看>>
PowerDesigner 使用的一些技巧(转)
查看>>
【敏捷开发】敏捷开发方法综述
查看>>
python字典实现原理-哈希函数-解决哈希冲突方法
查看>>
cetus系列~安装和基本配置
查看>>
Oracle数据库的安装详解
查看>>
Linux源码学习(2) 2013-2-21
查看>>
Node.js 实现 MySQL 数据库增删改查
查看>>
《世界是数字的》读后感
查看>>
ZJOI 最小割 CQOI 不同的最小割 (最小割分治)
查看>>
AOP日志记录
查看>>
js访问器属性之小问题
查看>>
ahjesus 部署lighttpd
查看>>