[ASP.NET MVC 小牛之路]04 - 依赖注入(DI)和Ninject
2013-08-07 21:37
751 查看
本人博客已转移至:http://www.exblr.com/liam
我们的理想情况是:一个组件可以不知道也可以不关心其他的组件,但通过提供的公开接口却可以实现其他组件的功能调用。这种情况就是所谓的松耦合。
举个简单的例子。我们要为商品定制一个“高级”的价钱计算器LinqValueCalculator,这个计算器需要实现IValueCalculator接口。如下代码所示:
Product类和前两篇博文中用到的是一样的。现在有个购物车ShoppingCart类,它需要有一个能计算购物车内商品总价钱的功能。但购物车本身没有计算的功能,因此,购物车要嵌入一个计算器组件,这个计算器组件可以是LinqValueCalculator组件,但不一定是LinqValueCalculator组件(以后购物车升级,可能会嵌入别的更高级的计算器)。那么我们可以这样定义购物车ShoppingCart类:
ShoppingCart类是通过IValueCalculator接口(而不是通过LinqValueCalculator)来计算商品总价钱的。如果以后购物车升级需要使用更高级的计算器,那么只需要改变第10行代码中new后面的对象(即把LinqValueCalculator换掉),其他的代码都不用变动。这样就实现了一定的松耦合。这时三者的关系如下图所示:
NinjectControllerFactory
现在暂时不解释这段代码,大家都看懂就看,看不懂就过,只要知道在ASP.NET MVC中使用Ninject要做这么一件事就行。
添加完这个类后,还要做一件事,就是在MVC框架中注册这个类。一般我们在Global.asax文件中的Application_Start方法中进行注册,如下所示:
注册后,MVC框架就会用NinjectControllerFactory类去获取Cotroller类的实例。在后续博文中会具体演示如何在ASP.NET MVC中使用Ninject,这里就不具体演示了,大家知道需要做这么两件事就行。
虽然我们前面花了很大功夫来学习Ninject就是为了在MVC中使用这样一个NinjectControllerFactory类,但是了解Ninject如何工作是非常有必要的。理解好了一种DI容器,可以使得开发和测试更简单、更高效。
参考:
《Pro ASP.NET MVC 3 Framework》
为什么需要依赖注入
在[ASP.NET MVC 小牛之路]系列的理解MVC模式文章中,我们提到MVC的一个重要特征是关注点分离(separation of concerns)。我们希望应用程序的各部分组件尽可能多的相互独立、尽可能少的相互依赖。我们的理想情况是:一个组件可以不知道也可以不关心其他的组件,但通过提供的公开接口却可以实现其他组件的功能调用。这种情况就是所谓的松耦合。
举个简单的例子。我们要为商品定制一个“高级”的价钱计算器LinqValueCalculator,这个计算器需要实现IValueCalculator接口。如下代码所示:
public interface IValueCalculator { decimal ValueProducts(params Product[] products); } public class LinqValueCalculator : IValueCalculator { public decimal ValueProducts(params Product[] products) { return products.Sum(p => p.Price); } }
Product类和前两篇博文中用到的是一样的。现在有个购物车ShoppingCart类,它需要有一个能计算购物车内商品总价钱的功能。但购物车本身没有计算的功能,因此,购物车要嵌入一个计算器组件,这个计算器组件可以是LinqValueCalculator组件,但不一定是LinqValueCalculator组件(以后购物车升级,可能会嵌入别的更高级的计算器)。那么我们可以这样定义购物车ShoppingCart类:
public class ShoppingCart { //计算购物车内商品总价钱 public decimal CalculateStockValue() { Product[] products = { new Product {Name = "西瓜", Category = "水果", Price = 2.3M}, new Product {Name = "苹果", Category = "水果", Price = 4.9M}, new Product {Name = "空心菜", Category = "蔬菜", Price = 2.2M}, new Product {Name = "地瓜", Category = "蔬菜", Price = 1.9M} }; IValueCalculator calculator = new LinqValueCalculator(); //计算商品总价钱 decimal totalValue = calculator.ValueProducts(products); return totalValue; } }
ShoppingCart类是通过IValueCalculator接口(而不是通过LinqValueCalculator)来计算商品总价钱的。如果以后购物车升级需要使用更高级的计算器,那么只需要改变第10行代码中new后面的对象(即把LinqValueCalculator换掉),其他的代码都不用变动。这样就实现了一定的松耦合。这时三者的关系如下图所示:
using System; using Ninject; using System.Web.Mvc; using System.Web.Routing; namespace MvcApplication1 { public class NinjectControllerFactory : DefaultControllerFactory { private IKernel ninjectKernel; public NinjectControllerFactory() { ninjectKernel = new StandardKernel(); AddBindings(); } protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) { return controllerType == null ? null : (IController)ninjectKernel.Get(controllerType); } private void AddBindings() { // 在这添加绑定, // 如:ninjectKernel.Bind<IProductRepository>().To<FakeProductRepository>(); } } }
NinjectControllerFactory
现在暂时不解释这段代码,大家都看懂就看,看不懂就过,只要知道在ASP.NET MVC中使用Ninject要做这么一件事就行。
添加完这个类后,还要做一件事,就是在MVC框架中注册这个类。一般我们在Global.asax文件中的Application_Start方法中进行注册,如下所示:
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory()); }
注册后,MVC框架就会用NinjectControllerFactory类去获取Cotroller类的实例。在后续博文中会具体演示如何在ASP.NET MVC中使用Ninject,这里就不具体演示了,大家知道需要做这么两件事就行。
虽然我们前面花了很大功夫来学习Ninject就是为了在MVC中使用这样一个NinjectControllerFactory类,但是了解Ninject如何工作是非常有必要的。理解好了一种DI容器,可以使得开发和测试更简单、更高效。
参考:
《Pro ASP.NET MVC 3 Framework》
相关文章推荐
- [ASP.NET MVC 小牛之路]04 - 依赖注入(DI)和Ninject
- [ASP.NET MVC 小牛之路]04 - 依赖注入(DI)和Ninject
- [ASP.NET MVC 小牛之路]04 - 依赖注入(DI)和Ninject
- [ASP.NET MVC 小牛之路]04 - 依赖注入(DI)和Ninject
- [ASP.NET MVC 小牛之路]04 - 依赖注入(DI)和Ninject
- [ASP.NET MVC 小牛之路]04 - 依赖注入(DI)和Ninject
- [ASP.NET MVC 小牛之路]05 - 使用 Ninject实现依赖注入
- ASP.NET MVC 5 (七-1)依赖项注入(DI)容器-Ninject
- ASP.NET MVC Ninject 实现依赖注入
- Asp.net MVC 中使用 Ninject 实现依赖注入
- Ninject--ASP.NET MVC 3中的依赖注入容器
- ADO.NET .net core2.0添加json文件并转化成类注入控制器使用 简单了解 iTextSharp实现HTML to PDF ASP.NET MVC 中 Autofac依赖注入DI 控制反转IOC 了解一下 C# AutoMapper 了解一下
- 《Pro ASP.NET MVC 3 Framework》学习笔记之五【依赖注入及ninject工具使用】
- ASP.NET MVC中的依赖倒置IOC/依赖注入DI, (MircroSoft.Practices.Unity)与asp.net mvc 3的融合
- ASP.NET MVC 中 Autofac依赖注入DI 控制反转IOC 了解一下
- 【ASP.NET MVC 学习笔记】- 05 依赖注入工具Ninject
- 依赖注入框架Autofac的简单使用,以及在 ASP.NET MVC 中的使用
- Spring.NET 1.3.1 新特性探索系列1——ASP.NET MVC的依赖注入
- ASP.NET_MVC使用Spring.Net.MVC依赖注入学习笔记
- 扩展ASP.NET MVC三层框架且使用StructureMap实现依赖注入1-Model层