分析Autofac如何实现Controller的Ioc(Inversion of Control)

简介:

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模块实现的原理。



本文转自JustRun博客园博客,原文链接:http://www.cnblogs.com/JustRun1983/archive/2012/10/19/2731654.html,如需转载请自行联系原作者

目录
相关文章
|
API
.net core工具组件系列之Autofac—— 第二篇:Autofac的3种依赖注入方式(构造函数注入、属性注入和方法注入),以及在过滤器里面实现依赖注入
本篇文章接前一篇,建议可以先看前篇文章,再看本文,会有更好的效果。前一篇跳转链接:https://www.cnblogs.com/weskynet/p/15046999.html
423 0
.net core工具组件系列之Autofac—— 第二篇:Autofac的3种依赖注入方式(构造函数注入、属性注入和方法注入),以及在过滤器里面实现依赖注入
|
7月前
|
Java Spring 容器
05Spring - IOC中bean标签和管理对象细节
05Spring - IOC中bean标签和管理对象细节
25 0
|
11月前
|
Java Spring 容器
深入理解Spring IOC之扩展篇(四)、Aware接口
深入理解Spring IOC之扩展篇(四)、Aware接口
109 0
|
11月前
|
XML Java 数据格式
深入理解Spring IOC(三) 、refresh方法中实例化前的准备工作
深入理解Spring IOC(三) 、refresh方法中实例化前的准备工作
46 0
|
Java 程序员 网络安全
spring4.1.8扩展实战之七:控制bean(BeanPostProcessor接口)
实战在容器初始化的时候对bean实例做设置
115 0
spring4.1.8扩展实战之七:控制bean(BeanPostProcessor接口)
|
开发框架 Java Spring
【Spring注解驱动开发】你还不会使用@Resource和@Inject注解?那你就out了!!
我在 冰河技术 微信公众号中发表的《【Spring注解驱动开发】使用@Autowired@Qualifier@Primary三大注解自动装配组件,你会了吗?》一文中,介绍了如何使用@Autowired、@Qualifier和@Primary注解自动装配Spring组件。那除了这三个注解以外,还有没有其他的注解可以自动装配组件呢?那必须有啊!今天,我们就一起说说@Resource注解和@Inject注解。
274 0
|
前端开发 图形学