源代码位置:\Web\Mvc\Processors: InitContextProcessor.cs
Config -> wojilu.Web.Mvc.CoreHandler.ProcessRequest - >
wojilu.Web.Mvc.CoreHandler.ProcessRequest: ProcessContext.Begin ->
RouteProcess InitContextProcess
上次我们说到了wojilu的路由系统,这次我们看看路由处理的下一步,内容初始化处理:
还记得一开始所说的,wojilu对于每一个请求,会将和这个请求有关的东西都放在一个ProcessContext里面。这个ProcessContext的内容随着处理过程而变更和增加。例如在路由处理结束后,路由的信息就被加入了这个ProcessContext里面了。这次介绍的InitContextProcess就是对ProcessContext的一个初始化。
这个处理的流程和其他处理流程一样,首先发一个系统广播,告诉侦听者InitContextProcessor被启动了,你可以在这里做一些过滤动作。
接下来,这里首次使用了IOC系统,每个系统对于初始化可能有自己的方法,这里使用wojilu的IOC系统加载一个
"contextInit"。当然,如果没有"contextInit",则使用一个默认的的ContextInitor。
1 internal class InitContextProcessor : ProcessorBase { 2 3 public override void Process( ProcessContext context ) { 4 5 MvcEventPublisher.Instance.BeginInitContext( context.ctx ); 6 if (context.ctx.utils.isSkipCurrentProcessor()) return ; 7 8 MvcContext ctx = context.ctx; 9 10 ContextInitBase initor = getContextInit(); 11 12 initor.InitViewer( ctx ); // 初始化当前登录用户(访问者) 13 initor.InitOwner( ctx ); // 初始化当前被访问对象(site或group或user) 14 initor.InitController( ctx ); // 初始化控制器 15 initor.InitPermission( ctx ); // 初始化权限检查 16 initor.InitApp( ctx ); // 初始化当前app 17 } 18 19 private ContextInitBase getContextInit() { 20 ContextInitBase initor = ObjectContext.GetByName( " contextInit " ) as ContextInitBase; 21 if (initor == null ) return new ContextInitDefault(); 22 return initor; 23 } 24 25 } 这个默认的内容初始化的代码里面,对于无效的Controller进行了过滤:
1 /// <summary> 2 /// 初始化当前 controller 3 /// </summary> 4 /// <param name="ctx"></param> 5 public virtual void InitController( MvcContext ctx ) { 6 ControllerBase controller = ControllerFactory.InitController( ctx ); 7 if (controller == null ) { 8 String typeName = ctx.route.getControllerNameWithoutRootNamespace(); 9 String msg = lang. get ( " exControllerNotExist " ) + " : " + typeName; 10 throw ctx.ex( HttpStatus.NotFound_404, msg ); 11 } 12 13 ctx.utils.setController( controller ); 14 } 从上一步的路由信息中获得的信息在这里第一次使用,如果路由中的controller不可用的话,这里直接抛出一个404页面找不到的错误,Process流程将在这里终止。
如果Controller是合法的话,这里的ProcessContext将被增加新的内容:Controller的信息。
Context内容:
路由信息(RouteProcess)
Controller信息(InitContextProcess)
打开wojilu\Web\Mvc:ControllerFactory.cs 看看InitController的代码吧。
1 /// <summary> 2 /// 根据当前上下文中的路由,创建相应的controller 3 /// </summary> 4 /// <param name="ctx"></param> 5 /// <returns></returns> 6 public static ControllerBase InitController( MvcContext ctx ) { 7 8 Route route = ctx.route; 9 10 List < String > rootNamespaceList = MvcConfig.Instance.RootNamespace; 11 12 foreach (String rootNamespace in rootNamespaceList) { 13 route.setRootNamespace( rootNamespace ); 14 String typeName = route.getControllerFullName(); 15 logger.Debug( " init contrller type= " + typeName ); 16 17 ControllerBase controller = FindController( typeName, ctx ); 18 if (controller != null ) return controller; 19 } 20 return null ; 21 } 第一步,拿出ctx里面的Route信息
第二步,通过反射的方法取得MVC系统里面的所有RootNameSpace。
这里的代码有一些不太爽的地方,这里先对RootNameSpace设定了值,然后获得了Controller的类型名称,然后去寻找Controller。如果找不到的话,继续对RootNameSpace设定值。。。。这里的问题是getControllerFull是route的方法,这样的话,必须每次都设定rootns,然后才能获得typeName。我觉得应该给getControllerFullName加一个参数。这样的话,只有在FindController成功的时候才setRootNamespace。可能因为更加深层次的关系作者要这么写。不过对于反复setRootNamespace总归有些纠结。。。
到此为止,我们的上下文里面有了Route和Controller信息了,差不多要去访问一下Controller了。
这一节的实际使用方法不是非常明显,估计没有特别的理由不会去自定义一个ContextInitor。
注意:官网将Context翻译为上下文
wojilu的1.7正式版将在近期正式Release,敬请期待。
我记录网址
欢迎大家加入我记录开发团队