日期:2014-05-16  浏览次数:20789 次

Asp.Net MVC4 系列--进阶篇之Controller(2)

调用Action的流程

IIS 接收到一个http请求,进入w3wp进程(如果是webgarden,先找到一个压力小的的w3wp),找到applicationpool,进入global.asax,进入路由,从controllerfactory找到一个controller,如果我们用了默认的controller,会解析出action名称和参数调用action(也可以手动直接在controller处理掉请求),返回并执行result,如图:


自定义controller factory

在上一章节,介绍了如果customize 一个controller(实现IController接口),现在介绍一个如何customizecontroller factory。

接口:


public interface IControllerFactory {
IController  CreateController(RequestContextrequestContext,
string controllerName);
SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext,
string controllerName);
void  ReleaseController(IControllercontroller);
}


 

说明:

CreateController : 接收request context和controller name(不包含”Controller”后缀),返回一个IController对象,用于创建Controller对象

GetControllerSessionBehavior:参数同上,返回一个SessionStateBehavior,控制创建出的controller的sessionstate对象

ReleaseController:

如果controller包含了一些需要手动释放的资源,可以在这个函数里统一释放

 

代码示例:

  public class CustControllerFactory : IControllerFactory
    {
        private string_nsFind;
        private string_assembly;
        public CustControllerFactory(string namespaceFind, string  assemblyName)
        {
            if(namespaceFind.Last() == '.') namespaceFind =namespaceFind.Remove(namespaceFind.Length - 1);
            _nsFind =namespaceFind;
            _assembly= assemblyName;
        }
        public IController CreateController(RequestContext requestContext, string controllerName)
        {
            var fullName = _nsFind + "." + controllerName + "Controller";
            var type =GetType().Assembly.GetTypes().FirstOrDefault(t => t.FullName == fullName);
            if (type== null)
            {
                return new TestController();
            }
            return (IController)Activator.CreateInstance(_assembly, fullName).Unwrap();
        }
 
        public SessionStateBehavior GetControllerSessionBehavior(RequestContextrequestContext, string controllerName)
        {
            return SessionStateBehavior.Default;
        }
 
        public void ReleaseController(IController controller)
        {
            var disposable = controller as IDisposable;
            if(disposable != null)
            {
               disposable.Dispose();
            }
        }
    }


代码说明:factory接收一个命名空间名称和assembly名称,在指定的范围内检索controller对象通过反射动态创建对象,如果找不到,返回一个默认的controller。

下一步,在global文件中注册factory:

protected void Application_Start()
        {
           AreaRegistration.RegisterAllAreas();
 
           WebApiConfig.Register(GlobalConfiguration.Configuration);
           FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
           RouteConfig.RegisterRoutes(RouteTable.Routes);
           BundleConfig.RegisterBundles(BundleTable.Bundles);
 
           ControllerBuilder.Current.SetControllerFactory(new
CustControllerFactory("MVCRouteStudy.Controllers","MVCRouteStudy"));
        }


 

可以看到,在最后一行,我注册了我手动创建的factory。

测试一下这个factory,先访问一个不存在controller:


访问一个存在的:



注意:此例只作为一个简单的实现,甚至没有捕捉异常。现实应用中,场景要复杂的多,自定义的controller工厂在创建controller对象时,一般不仅仅简单的创建一个实