使用Spring.Net 1.3.2实现Container(IoC)(二)ASP.NET MVC、ControllerFactory
2011-10-16 22:19
671 查看
ControllerFactory
ControllerFactory是基于路由的组件,它选择正确的controller并对其实例化。default factory会查找实现了IController并且以Controller结尾的类,然后通过反射使用无参构造函数进行实例化。但如果您希望使用依赖注入,就不能再使用default factory,而必须使用支持IoC的controller factory。
使用支持IoC(依赖注入)的controller factory, 优点在于松耦合,可测试性很好。如果在Controller里面想要使用某些Service,要么new出来,要么用单例的形式,如UserService.Instance,这样想对Controller写单元测试都不容易,它和这些Service耦合太紧密,无法将这些Service替换成Stub实现。因此,松耦合是必须的。要实现这个功能,必须让依赖注入框架来创建Controller,才有可能注入依赖并组装对象。MVC里面有一个ControllerFactory的东西,可以使用来达到这个目的。
方法:
1、写一个类,继承自DefaultControllerFactory,例如 SpringControllerFactory : DefaultControllerFactory
2、覆盖方法GetControllerInstance,使用依赖注入框架来创建Conroller
3、修改Global.asax.cs, 在Application_Start内注册使用自己的ControllerFactory,
ControllerBuilder.Current.SetControllerFactory(new SpringControllerFactory())
4、对Controller进行构造函数注入,例如:
public class AccountController : Controller { private IRepository repository; public IRepository Repository { get { return repository; } set { repository = value; } } }
从现在开始,所有的Controller都是通过依赖注入框架来创建的,新增的Service就在依赖注入框架里面注册,Controller要使用哪些Service就往构造函数里加,反正框架会注入进来。
MVCQuick的ControllerFactory
在“使用Spring.Net 1.3.2实现Container(IoC)(一)”已使用Spring.NET实现了一个简单的IoC容器ClassicContainer,故实现支持IoC的ControllerFactory手到擒来。
MVCQuick的ControllerFactory实现代码
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing; using System.Collections; using MVCQuick.Framework.Container; namespace MVCQuick.Framework.Mvc { public class ClassicControllerFactory : DefaultControllerFactory { public override IController CreateController(RequestContext requestContext, string controllerName) { IController controller = ClassicContainer.GetObject(controllerName) as IController; if (controller == null) { controller = base.CreateController(requestContext, controllerName); } AddActionInvokerTo(controller); return controller; } protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) { IController controller = null; if (controllerType != null) { var controllers = ClassicContainer.GetObjects(controllerType); if (controllers.Count > 0) { controller = (IController)controllers.Cast<DictionaryEntry>().First().Value; } } else { controller = base.GetControllerInstance(requestContext, controllerType); } AddActionInvokerTo(controller); return controller; } protected virtual void AddActionInvokerTo(IController controller) { if (controller == null) return; if (typeof(Controller).IsAssignableFrom(controller.GetType())) { ((Controller)controller).ActionInvoker = new ClassicActionInvoker(); } } } }
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using MVCQuick.Framework.Container; namespace MVCQuick.Framework.Mvc { ///<summary> /// ActionInvoker implementation that enables the <see cref="IApplicationContext"/>to satisfy dependencies on ActionFilter attributes. ///</summary> public class ClassicActionInvoker : ControllerActionInvoker { ///<summary> /// ///</summary> public ClassicActionInvoker() { } ///<summary> /// Retrieves information about the action filters. ///</summary> ///<param name="controllerContext">The controller context.</param> ///<param name="actionDescriptor">The action descriptor.</param> ///<returns>Information about the action filters.</returns> protected override FilterInfo GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor) { //let the base class do the actual work as usual var filterInfo = base.GetFilters(controllerContext, actionDescriptor); //configure each collection of filters using the IApplicationContext foreach (IActionFilter filter in filterInfo.ActionFilters.Where(f => f != null)) { ClassicContainer.ConfigureObject(filter, filter.GetType().FullName); } foreach (IAuthorizationFilter filter in filterInfo.AuthorizationFilters.Where(f => f != null)) { ClassicContainer.ConfigureObject(filter, filter.GetType().FullName); } foreach (IExceptionFilter filter in filterInfo.ExceptionFilters.Where(f => f != null)) { ClassicContainer.ConfigureObject(filter, filter.GetType().FullName); } foreach (IResultFilter filter in filterInfo.ResultFilters.Where(f => f != null)) { ClassicContainer.ConfigureObject(filter, filter.GetType().FullName); } return filterInfo; } } }
ClassicControllerFactory使用方法
在Global.asax.cs类Application_Start()添加代码
//Register Repository ClassicContainer.Register<NHibernateRepository>("NHibernateRepository");
//Register Controller IDictionary properties = new Dictionary<String, Object>(); properties.Add("Repository", ClassicContainer.GetObject("NHibernateRepository")); ClassicContainer.Register<AccountController>("Account", properties); ClassicContainer.Register<CheckoutController>("Checkout", properties); ClassicContainer.Register<HomeController>("Home", properties); ClassicContainer.Register<ShoppingCartController>("ShoppingCart", properties); ClassicContainer.Register<StoreController>("Store", properties); ClassicContainer.Register<StoreManagerController>("StoreManager", properties); ClassicContainer.Register<SampleDataController>("SampleData", properties);
//Set ControllerFactory ControllerBuilder.Current.SetControllerFactory(typeof(ClassicControllerFactory));
源代码下载:http://mvcquick.codeplex.com/
相关文章推荐
- 使用Spring.Net 1.3.2实现Container(IoC)(一)IoC、DI、Spring.NET、Ioc Container、 ClassicContainer
- ASP.NET MVC中使用Spring.Net实现IOC和DI
- 使用Spring.Net 1.3.2实现Container(IoC)(三)架构模式IoC
- 使用Spring.Net 1.3.2实现Container(IoC)(四)Spring.NET
- ASP.NET MVC 中使用Spring.NET实现简单的属性注入
- ASP.NET MVC如何使用Unity实现Ioc详解
- ADO.NET .net core2.0添加json文件并转化成类注入控制器使用 简单了解 iTextSharp实现HTML to PDF ASP.NET MVC 中 Autofac依赖注入DI 控制反转IOC 了解一下 C# AutoMapper 了解一下
- ASP.NET MVC中使用Unity Ioc Container
- ASP.NET MVC 中使用Spring.NET实现简单的属性注入
- 【无私分享:从入门到精通ASP.NET MVC】从0开始,一起搭框架、做项目(5.1) 登录功能的实现,开始接触Spring IOC、DI
- ASP.NET MVC中使用Unity Ioc Container
- ASP.NET MVC中使用Unity Ioc Container
- 在ASP.NET MVC Framework中使用IErrorDataInfo接口实现验证(翻的)
- 使用Common.Logging 1.2实现Logging(二)ASP.NET MVC、Filter
- 使用ASP.NET MVC 4 Async Action+jQuery实现消息通知机制的实现代码
- 在 Asp.NET MVC 中使用 SignalR 实现推送功能
- Asp.net2005 使用 NVelocity 实现 MVC
- 简单的三层asp.net webForm使用Ninject实现Ioc
- 【EntityFramework系列教程三,翻译】在ASP.NET MVC程序中使用EntityFramework对数据进行排序、过滤筛选以及实现分页
- [11] 使用 MVC 5 的 EF6 Code First 入门 系列:为ASP.NET MVC应用程序实现继承