• 我记录网站综合系统 技术原理解析[6:内容初始化处理]



    源代码位置:\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 == nullreturn 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 != nullreturn 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,敬请期待。

    我记录网址 http://www.wojilu.com/

    欢迎大家加入我记录开发团队

  • 相关阅读:
    FDQuery 怎么能插入NULL参数
    datasnap的监督功能TCP链接监督功能
    Delphi 操作Ini文件
    博客园的自定义皮肤
    Dell latitude e5470笔记本BIOS修改与U盘启动
    Delphi TNetHTTPClient Authorization not working
    增加fmx快速生成界面
    CF1654FMinimal String Xoration【倍增】
    P5044[IOI2018] meetings 会议【dp,笛卡尔树,线段树二分】
    CF838CFuture Failure【dp,子集卷积】
  • 原文地址:https://www.cnblogs.com/TextEditor/p/2080770.html
Copyright © 2020-2023  润新知