本文介绍一下ASP.NET mvc中与Controller相关的高级特性,下图展示了一个MVC请求从接收到响应的过程要经历的组件的流程。
下面我们主要就来谈谈ASP.NET MVC5中的Controller Factory和Action Invoker。这两个组件通过名字也能够知道这它们的用途。
controller factory主要是用来创建Contoller的实例,而action invoker是用来查找并调用一个Contoller类中的Action方法。MVC框架本自己就已经我们实现了这两个组件,下面我们就分别举例说明一下如何在ASP.NET MVC5中,自己实现一个Controller Factory、Action Invoker,并介绍一下使用内置组件Controller Factory、Action Invoker的方法。
对于ASP.NET MVC中的大多数类或组件,我们想要真正的搞懂它,最好的方式就是继承对应的接口或抽象类,然后自己写一个它的实现类。同理要了解Controller Factory是怎么创建一个Controller实例的我们也可以自己写一个Controller Factory我类,所有的Controller Factory都使用了接口IControllerFactory。
首先,我们来看看IControllerFactory在MVC框架中是怎么定义的:
1、CreateController:负责创建Controller实例,返回类型是IController类型
2、GetControllerSessionBehavior:负责设置Controller的Session行为
3、ReleaseController:可以释放Controlller相关的资源
下面我们看看一个自定义自定义的Controller Factory的完整例子:
HttpContext:http请求上下文。
RouteData:MVC路由相关信息。
第二个是要创建的controller名。
在CreateController方法的最后使用了MVC内置的依赖注入容器解析类来创建一个类的实例:
自定义Controller Factory类在项目中要生效,必须要注册到MVC5框架中。注册自定义Controller Factory类会用到类ControllerBuilder类,如下:
注意:上面实现了一个自定义了的ControllerFactory,你应该明白了ControllerFactory的作用了,但是不建议你自己实现ControllerFactory,因为你负责处理一些潜在的问题,比如:有歧义的Controller名字--不同命名空间相同名称的Controller类,构造函数异常等等。其实最快速有效的方式是使用MVC框架的自带的Controller Factory,DefaultControllerFactory,因为这些问题都为我们解决了。但是要使用DefaultControllerFactory,Controller类必须要满足一下几个条件:
1、类必须是public的
2、类不能够是abstract抽象的
3、类不能够带有泛型参数
4、类名必须要以Controller结尾
5、类必须实现接口IController
DefaultControllerFactory自身会维护保持这一个满足以上条件的类列表,这样不用每次请求都去项目中搜索这样类。
我们可以设置指定命名空间的Controller就先去匹配,如下:
注意:这里两个Add是不分先后顺序的,并不表示写在前面就先去对应命名空间搜索。
自定义DefaultControllerFactory创建Controlller的实例的方式有很多种,有时为了把我们的项目耦合性降低,我们一般会引入DI(依赖注入)。
1、使用MVC自带的Dependency Resolver
当有Dependency Resolver可用时,DefaultControllerFactory会使用它来创建Controller实例。
定义一个Dependency Resolver
上面使用依赖注入DI(Ioc框架)--Ninject,最后在Gloabl中注册上面的NinjectDependencyResolver
2、使用一个Controller Activator
除了上面使用DependencyResolver来控制DefaultControllerFactory创建Controller,还可以定义一个Controller Activator,然后把这个类的实例通过DefaultControllerFactory的构造函数传进去。
我们先来看一看定义一个Controller Activator要用到的接口IControllerActivator: