分析Autofac如何实现Controller的Ioc(Inversion of Control)
2012-10-19 21:33 JustRun 阅读(7354) 评论(13) 编辑 收藏 举报Autofac是一个Ioc框架,最大的特点应该是可以不用配置文件,直接用C#代码来注册。
Autofac同时也提供了对于Asp.net MVC的扩展。
这里是Autofac的文档,介绍如何在MVC项目中集成使用:
protected void Application_Start() { var builder = new ContainerBuilder(); builder.RegisterControllers(typeof(MvcApplication).Assembly); var container = builder.Build(); DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); // Other MVC setup...
解释一下里面的过程:
1. 首先创建一个ContainerBuilder(它会稍后为我们提供一个容器,我们可以从中取出我们所需的对象实例)
2. 注册当前Assembly中的所有Controllers到Builder,这样Builder就获取了当前MVC项目中的所有Controller类型
3. 创建容器
4. 用AutofacDependencyResolver替换MVC默认的DependencyResolver
OK. 到这里, 前面的还容易理解,最后一个DependencyResolver做了什么? 要了解DependencyResolver, 需要先知道ControllerFactory
MVC中的ControllerFactory
MVC请求的过程,就是根据请求的URL找到匹配的Route, Route解析出来对应的Controller的名字, 然后根据名字,找到对应的Controller类型,然后实例化一个Controller的对象响应请求。
上面粗体标出的,就是DefaultControllerFactory做的事情,也就是它的方法CreateController方法:
public virtual IController CreateController(RequestContext requestContext, string controllerName)
CreateController方法又主要依赖于GetControllerType和GetControllerInstance方法:
protected internal virtual Type GetControllerType(RequestContext requestContext, string controllerName) protected internal virtual IController GetControllerInstance(RequestContext requestContext, Type controllerType)
看到这么多的virtual方法,是不是很激动? 这个不是明显是让我们继承和override的嘛。假如我们override这里的GetControllerInstance方法,然后根据这里的controllerType从Ioc容器中获取这个ControllerType的实例,不就万事OK了吗?
没错,继承和重写GetControllerInstance方法的确可以实现Controller的Ioc, 然后在Application_Start()里面,使用下面这行代码,替换掉DefaultControllerFactory.
ControllerBuilder.Current.SetControllerFactory(new MyControllerFactory(_container));
说好的DependencyResolver呢?
其实DefaultControllerFactory中的GetControllerInstance,调用了IDependencyResolver接口定义的方法GetService获取实例。通过继承这个接口,替换原有的DependencyResolver, 对于MVC原有的改动更小。所以使用通过继承IDependencyResolver 接口的方式来实现更好. 这就是开篇我们看到的:
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
IDependencyResolver借口
public interface IDependencyResolver { object GetService(Type serviceType); IEnumerableGetServices(Type serviceType); }
想看看AutofacDependencyResolver的源代码是如何根据Type从容器中获取实例的, 可以到这里
思考和实践: 什么时候用到ControllerFactory
Asp.net MVC中的Area的使用,应该大家比较熟悉了。它是用来解决大的项目,多人开发的情况的。area实现的原理,是通过命名空间来区分即使名字相同的Controller的。可是无论如何,area都是在一个project里面的.
如何能够分离area到不同的project中呢? 这里的GetControllerType方法就是很好的突破口。下次探讨一下如何实现area分离到不同的project中,方便较大的项目。这也是Orchard CMS模块实现的原理。

本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名justrun(包含链接)。如您有任何疑问或者授权方面的协商,请给我留言。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· [AI/GPT/综述] AI Agent的设计模式综述