日期:2014-05-16 浏览次数:20871 次
IIS 接收到一个http请求,进入w3wp进程(如果是webgarden,先找到一个压力小的的w3wp),找到applicationpool,进入global.asax,进入路由,从controllerfactory找到一个controller,如果我们用了默认的controller,会解析出action名称和参数调用action(也可以手动直接在controller处理掉请求),返回并执行result,如图:
在上一章节,介绍了如果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对象时,一般不仅仅简单的创建一个实