《Pro ASP.NET MVC 3 Framework》学习笔记之八【Ninject的使用-上】

简介: 本次的笔记分为三个部分:Ninject(依赖注入容器,前面有介绍的,如果你第一次路过这里,可以先看下我前面的笔记),NUnit(单元测试工具),Moq(用来模拟在单元测试中的接口实现).今天我做的笔记是关于第一部分:Ninject. 如果你对依赖注入(DI)没有任何的了解,你可以看看我前面的笔记或者在网上搜索相关的资料进行了解。

本次的笔记分为三个部分:Ninject(依赖注入容器,前面有介绍的,如果你第一次路过这里,可以先看下我前面的笔记),NUnit(单元测试工具),Moq(用来模拟在单元测试中的接口实现).今天我做的笔记是关于第一部分:Ninject.

如果你对依赖注入(DI)没有任何的了解,你可以看看我前面的笔记或者在网上搜索相关的资料进行了解。

下面通过一个实例来介绍Ninject的使用,首先我们需要猛击这里下载相关的DLL。我们仍然用到的前面的Product,实现技术所有Product的总价值。下面通过几个步骤来具体的介绍:

1.创建一个Console Application,如果你不介意,我们暂且给它命名为NinjectDemo.接下来我们创建一个Product类,如下所示:

namespace NinjectDemo
{
public class Product
{
public int ProductID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public string Category { set; get; }
}
}

接着创建一个接口IValueCalculator,如下所示:

namespace NinjectDemo
{
public interface IValueCalculator
{
decimal ValueProducts(params Product[] products);
}
}

接着创建一个接口实现,如下所示:

namespace NinjectDemo
{
public class LinqValueCalculator:IValueCalculator
{
public decimal ValueProducts(params Product[] products)
{
return products.Sum(p => p.Price);
}
}
}

这里我们计算Products的总价用了LINQ的扩展方法(关于扩展方法在前面的笔记有介绍),当然这里你完全可以自己遍历Products求和并返回一个Decimal类型的值。下面我们创建一个类用来实现依赖注入。ShoppingCart.cs如下所示:

    public class ShoppingCart
{
private IValueCalculator calculator;
public ShoppingCart(IValueCalculator calcParam)
{
calculator = calcParam;
}

public decimal CalculateStockValue()
{
Product[] products = {
new Product() { Name = "Kayak", Price = 275M},
new Product() { Name = "Lifejacket", Price = 48.95M},
new Product() { Name = "Soccer ball", Price = 19.50M},
new Product() { Name = "Stadium", Price = 79500M}
};
decimal totalValue = calculator.ValueProducts(products);
return totalValue;
}
}

2.这里用到的依赖注入就是我们前面笔记里面的介绍的一种Constructor Injection(构造器注入),通过接口实现的实例作为参数传递给ShoppingCart的构造器来实现ShoppingCart与LinqValueCalculator(IValueCalculator接口实现)的解耦。下面的图很好的阐释了这几个类或接口直接的关系,如下所示:

呵呵,其实解耦的操作,按我自己的理解就是达到在两个耦合的对象之间引入一个"第三者",这样我们目的就达到了。当然在程序里面我常常需要这样的"第三者",现实的生活可不要这样,呵呵。这里的比方不是很恰当哈,大家就不要深究了。这里的ShoppingCart与LinqValueCalculator都依赖于IValueCalculator,但是彼此之间并没有直接的联系,甚至不知道彼此的存在。我可以改变LinqValueCalculator的实现,或者干脆用其他的方式来实现IValueCalculator接口,而不会让ShoppingCart有任何察觉,因为现在的它已经不在那么聪明了,呵呵。

3.从上面的几个类和接口之间的关系图我们可以发现,ShoppingCart,IValueCalculator,LinqValueCalculator这三个类型都跟Product有直接的联系。我们并不用担心,因为这里的Product等效于Domain Model Type(领域模型类型),并且我期望这样的类跟应用程序的其他部分发生强耦合。当然如果我们不是为了创建MVC程序,我们可能会有不同的看法,或许也会为Product采取解耦操作。

4.我们的目标就是要创建ShoppingCart的实例并且以IValueCalculator实现作为构造器参数的方式来注入。这正好是Ninject(DI容器)为我们充当的角色,在我们使用Ninject之前,我先引入Ninject.dll,并且查看一些我们项目的属性确定一下我们的Target Framework是. NET Framework 4,如果是 .NET Framework 4 Client Profile,在后面编译时会报错提示没有Ninject命名空间,原因是Client Profile会忽略Ninject.dll。

5.关于Ninject的使用,我们可以通过下面的代码(Console Application的Program.cs).如下所示:

        static void Main(string[] args)
{
IKernel ninjectKernel = new StandardKernel();
ninjectKernel.Bind<IValueCalculator>().To<LinqValueCalculator>();
//获取接口实现
IValueCalculator calcImpl = ninjectKernel.Get<IValueCalculator>();

//创建ShoppingCart的实例并注入依赖
ShoppingCart cart = new ShoppingCart(calcImpl);

//执行
Console.WriteLine("Tatol:{0:c}", cart.CalculateStockValue());

}

接下来我们对加粗的代码进行介绍,使用Ninject,我们首先创建一个IKernel对象,通过这个对象来与Ninject交互。

一旦我们创建了IKernel对象后,接下需要通过Ninject做两个操作。

第一,绑定我们要创建的接口类型,在这里就是要告诉Ninject,当收到接口实现的请求时,为我们创建一个LinqValueCalculator的实例并返回给我们。这里我们使用的是在IKernel里面定义的Bind<T>()...To<T>()方法。正如代码:ninjectKernel.Bind<IValueCalculator>().To<LinqValueCalculator>();这样我们就完成了注册工作了(前面相关的笔记有提到DI容器的使用)。

第二,使用Ninject的Get()方法创建接口实现的对象,这也就是我需要的作为参数传递给ShoppingCart构造器的,还记得吧!嘿嘿!

Ok,我们再来梳理一些刚才的思路,首先我们是解耦,并且通过将IValueCalculator的实现的对象作为参数传递给ShoppingCart构造的方式实现了;

接下来,我们通过DI容器来管理和获取这个参数,而我们又是通过Ninject来实现的。到这里我们对Ninject应该有了一些了解了吧。

好了,今天的笔记就到这里。明天会对Ninject的用法进一步学习。

初学MVC,加上跛脚的英语,笔记里面肯定有理解不准确和错误的地方,请路过的朋友们多多帮助!谢谢!

晚安!

相关文章
|
Web App开发 .NET 容器
一起谈.NET技术,ASP.NET MVC3 让依赖注入来的更简单(新补充了Ninject示例)
  昨天,我写了一篇文章(参见:ASP.NET MVC 依赖注入),这种实现方式我个人一直感觉不太顺,在写出来与大家一起分享的同时,   也是想让大家提提自己的建议, 今天下载了微软发布的最新的 ASP.
883 0
|
3月前
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
38 0
|
29天前
|
开发框架 前端开发 .NET
进入ASP .net mvc的世界
进入ASP .net mvc的世界
28 0
|
1月前
|
开发框架 前端开发 .NET
C# .NET面试系列六:ASP.NET MVC
<h2>ASP.NET MVC #### 1. MVC 中的 TempData\ViewBag\ViewData 区别? 在ASP.NET MVC中,TempData、ViewBag 和 ViewData 都是用于在控制器和视图之间传递数据的机制,但它们有一些区别。 <b>TempData:</b> 1、生命周期 ```c# TempData 的生命周期是短暂的,数据只在当前请求和下一次请求之间有效。一旦数据被读取,它就会被标记为已读,下一次请求时就会被清除。 ``` 2、用途 ```c# 主要用于在两个动作之间传递数据,例如在一个动作中设置 TempData,然后在重定向到另
95 5
|
8月前
|
存储 开发框架 前端开发
[回馈]ASP.NET Core MVC开发实战之商城系统(五)
经过一段时间的准备,新的一期【ASP.NET Core MVC开发实战之商城系统】已经开始,在之前的文章中,讲解了商城系统的整体功能设计,页面布局设计,环境搭建,系统配置,及首页【商品类型,banner条,友情链接,降价促销,新品爆款】,商品列表页面,商品详情等功能的开发,今天继续讲解购物车功能开发,仅供学习分享使用,如有不足之处,还请指正。
114 0
|
9月前
|
开发框架 前端开发 .NET
[回馈]ASP.NET Core MVC开发实战之商城系统(一)
[回馈]ASP.NET Core MVC开发实战之商城系统(一)
113 0
|
9月前
|
SQL 开发框架 前端开发
[回馈]ASP.NET Core MVC开发实战之商城系统(开篇)
[回馈]ASP.NET Core MVC开发实战之商城系统(开篇)
142 0
|
9月前
|
开发框架 缓存 JSON
ASP.NET Core MVC 从入门到精通之Filter
ASP.NET Core MVC 从入门到精通之Filter
120 0
|
9月前
|
开发框架 前端开发 .NET
ASP.NET Core MVC 从入门到精通之自动映射(二)
ASP.NET Core MVC 从入门到精通之自动映射(二)
60 0
|
5月前
|
开发框架 自然语言处理 前端开发
基于ASP.NET MVC开发的、开源的个人博客系统
基于ASP.NET MVC开发的、开源的个人博客系统
51 0