ASP.NET MVC4学习笔记之Controller激活的扩展
一. 为什么要进行扩展
在前面的分析中,我们知道默认的Controller激活系统只能实例化无参构造函数的Controller类型,但在某些情况一下,我们希望某些服务的实例能够自动注入到Controller实例中,从而达到服务接口和实现的隔离,减小重复的代码,提高系统的可维护性和灵活性。也就是说我们希望在Controller激活中引入依赖注入。关于依赖注入的概念这里就不解释了,请自行查询相关的资料。基于.net依赖注入框架也有很多,下面的例子主要使用微软企业库的Unity。
在上一节的分析中,我们知道Controller的激活实际是包括获取IControllerFacotry和IController实例, 在这两个级别都可以引入扩展实现在我们的目的,现在具体来看一下。
一.实列化IControllerFactory Level
在这个Level我们知道了路由系统提供的路由信息,当然甚至可以从头到尾自定义实现一个ControllerFactory,包括Controller类型的确定和实例化,但通常没什么必要。我们目标是在Controller实例化阶段注入服务实例,主要还是在Controller实例化阶段。
二. 实列化Controller Level
在这一阶段,我们已经确定Controller的类型,通过上一节的分析,有三个点我们可以引入依赖注入。我们假设有一个要显示所有Customer信息的页面,在其中应用了仓储模式,在CustomerController实例化进自动注入仓储的实例。
1. 继承DefaultControllerFactory,重写GetControllerInstance方法。大概的代码如下:
public class UnityControllerFactory : DefaultControllerFactory
{
public IUnityContainer Container
{
get;
private set;
}
public UnityControllerFactory(IUnityContainer container)
{
this.Container = container;
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
return (IController)this.Container.Resolve(controllerType);
}
}
然后在Global.asax的Application_Start中注册
private void RegisterUnityControllerFactory()
{
IUnityContainer container = new UnityContainer();
container.RegisterType<ICustomerRepository, CustomerRepository>();
ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory(container));
}
2. 自定义实现IControllerActivator。大概的代码如下:
public class UnityControllerActivator : IControllerActivator
{
public IUnityContainer Container
{
get;
private set;
}
public UnityControllerActivator(IUnityContainer c)
{
this.Container = c;
}
public IController Create(RequestContext requestContext, Type controllerType)
{
return (IController)this.Container.Resolve(controllerType);
}
}
注册代码:
private void RegisterUnityControllerActivator()
{
IUnityContainer container = new UnityContainer();
container.RegisterType<ICustomerRepository, CustomerRepository>();
ControllerBuilder.Current.SetControllerFactory(new DefaultControllerFactory(new UnityControllerActivator(container)));
}
3.自定义实现全局的IDependencyResolver
public class UnityDependencyResolver : IDependencyResolver
{
private IUnityContainer Container
{
get;
set;
} public UnityDependencyResolver()
{
this.Container = new UnityContainer();
} public UnityDependencyResolver RegisterType<TFrom, TTo>() where TTo : TFrom
{
this.Container.RegisterType<TFrom, TTo>();
return this;
} public object GetService(Type serviceType)
{
try
{
return this.Container.Resolve(serviceType);
}
catch(ResolutionFailedException)
{
return null;
}
} public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return this.Container.ResolveAll(serviceType);
}
catch (ResolutionFailedException)
{
return null;
}
}
注册代码:
private void SetDependencyResolver()
{
UnityDependencyResolver resolver = new UnityDependencyResolver();
resolver.RegisterType<ICustomerRepository, CustomerRepository>();
DependencyResolver.SetResolver(resolver);
}
三.真的要扩展吗?
天下没有完美的东西,引入一样东西我们必须要充分认识它的优势,也要认清它的副作用。在实际项目中,个人觉得大部分情况是没必要在Controller这个Level引入依赖注入,在Controller的Action中,通常我们要调用业务逻辑服务,业务逻辑的服务接口通常是没必要再引入一层另外的抽象。
另外,在这里大致总结一下,在Action中大概有两种方式来调用业务逻辑,一种利用Command模式,即把每个Action 对一个Command,在Command中再调用业务逻辑服务.一种是每个Controller包含一个或多个粗粒度的业务包装服务类,每个Action中直接调用一个或多个服务类处理。具体使用那一种模式,应根据你的项目情况来决定,这里不展开细说了。
最后所有的测试代码可以在这里下载http://files.cnblogs.com/jjyjjyjjy/TestAsp_Net_Mvc_ControllerActivator_DI.rar
ASP.NET MVC4学习笔记之Controller激活的扩展的更多相关文章
- ASP.NET MVC4学习笔记之Controller的激活
一. 高层相关类说明 当路由系统根据请求Url收集路由信息后,下一步就要将路由信息传给Controller激活系统,Controller激活系统负责实现了IController接口的Controlle ...
- ASP.NET MVC 学习笔记-7.自定义配置信息 ASP.NET MVC 学习笔记-6.异步控制器 ASP.NET MVC 学习笔记-5.Controller与View的数据传递 ASP.NET MVC 学习笔记-4.ASP.NET MVC中Ajax的应用 ASP.NET MVC 学习笔记-3.面向对象设计原则
ASP.NET MVC 学习笔记-7.自定义配置信息 ASP.NET程序中的web.config文件中,在appSettings这个配置节中能够保存一些配置,比如, 1 <appSettin ...
- asp.net mvc4 学习笔记一(基本原理)
做了8年的asp.net webform,用过MVVM但还没用过MVC , 虽然项目不用MVC,但是还是想了解一下,今天第二天学习,以下是学习心得. VS2012默认带有asp.net mvc3和as ...
- ASP.NET MVC4学习笔记路由系统概念与应用篇
一.概念 1.路由是计算机网络中的一个技术概念,表示把数据包从一个网段转发至另一网段.ASP.NET中的路由系统作用类似,其作用是把请求Url映射到相应的"资源"上,资源可以是一段 ...
- ASP.NET MVC4学习笔记之总体概述
断断续续使用ASP.NET MVC框架也有一年多了,也算积累了一些经验,唉,一直想写一些笔记好好总结一下,人太懒不想动笔,今天终于决定开始.希望自己能坚持下去. 这篇文章大体介绍ASP.NET MVC ...
- ASP.NET MVC5学习笔记之Controller同步执行架构分析
在开始之前,声明一下,由于ASP.NET MVC5正式发布了,后面的分析将基于ASP.NET MVC5最新的源代码.在前面的内容我们分析了怎样根据路由信息来确定Controller的类型,并最终生成C ...
- ASP.NET MVC4学习笔记路由系统实现
一.路由实现 路由系统实际是一个实现了ASP.NET IHttpModule接口的模块,通过注册HttpApplication的PostResolveRequestCache 事件对Url路由处理.总 ...
- ASP.NET MVC4学习笔记
一.MVC简介
- ASP.NET MVC5学习笔记之Controller执行ControllerDescriptor和ActionDescriptor
一. ControllerDescriptor说明 ControllerDescriptor是一个抽象类,它定义的接口代码如下: public abstract class ControllerDes ...
随机推荐
- NYOJ 55-懒省事的小明
点击打开链接 懒省事的小明 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 小明很想吃果子,正好果园果子熟了.在果园里,小明已经将所有的果子打了下来,而且按果 ...
- hbase的rowkey简单设计
问题: 需要查询某一用户某时间做了什么,PlatID和vopenid可以保证一个用户唯一,但同一时间同一用户可能日志有多条. 使用PlatID(int).vopenid(int)和dtTime(dat ...
- (转)c#多线程 Invoke方法的使用
原文地址:http://www.cnblogs.com/lovko/archive/2008/12/19/1358748.html 在多线程编程中,我们经常要在工作线程中去更新界面显示,而在多线程中直 ...
- jqGrid(struts2+jdbc+jsp)增删改查的例子
前几日一直在找关于Java操作jqgrid返回json的例子,在网上也看了不少东西,结果都没几个合理的,于是本人结合网上的零散数据进行整理,完成了 一个比较完整的jqgrid小例子,考虑到还有很多 ...
- 访问控制符private,default,protect和public
程序,通过封装以实现"高内聚,内耦合". 个人理解,类内,包内,子类和所有类,是java的四个范围. private表示作用区域为类内,即只是自己(像牙刷). default表示作 ...
- IIS报错,App_global.asax.×××.dll拒绝访问
解决方案: ①找到C:\Windows下的temp文件夹 ②属性->安全->编辑->添加IIS_IUSERS,给其添加上可读写的权限,然后应用,确定即可
- Office2010安装错误
Office2010安装“错误1406.安装程序无法将值Assembly写入注册表项” 我们在安装Office2010的时候,会遇到如上所示的错误. 今天我自己在安装的过程中就遇到类似的情况.由于我原 ...
- Android学习笔记之AndroidManifest.xml文件解析
一.关于AndroidManifest.xml AndroidManifest.xml 是每个android程序中必须的文件.它位于整个项目的根目录,描述了package中暴露的组件(activiti ...
- 获取AX的窗口所有控件的lableID及内容
思路,穷举Forms\TargetFormName 在AOT上面的路径得到TreeNode, 遍历各控件的属性. a1,先读Label属性,没有就读Caption属性及Text属性. a2,若a1取不 ...
- ENVI如何打开IRS P6的AWIFS的ges及LISS3的ges文件?
AWIFS文件下文件名如下:ID2010236001.hdrID2010236001_2.gesID2010236001_3.gesID2010236001_4.gesID2010236001_5.g ...