首先说明下P5对ViewEngine的改进,在老版本中,系统牵涉到ViewEngine管理的有两个接口,分别是: IViewEngine, IViewLocator,其中IVewEngine负责呈现View,IViewLocator负责对View的路径处理.同时,在Controller中对ViewEngine进行选择,让后在执行的时候将ViewEngine传递到ViewResult中,最后ViewResult使用ViewEngine来呈现ui.老版本的View部分大致类图如下:
它的执行流程大致如下:MVC框架根据Routing数据找到对应的Controller,而Controller中将根据IViewLocate来初始化一个ViewEngine(IViewLocater一般用来做路径选择)然后执行Controller的Execute方法,该方法间接通过ControllerActionInvoker来执行Action,每个Action都会返回一个ActionResult对象,然后,它执行ActionResult的ExecuteResult方法.系统有很多种ActionResult,当该ActionResult为ViewResult的时候,Controller会将自身的ViewEngine传递你这个ViewResult,在ViewResult中再最终使用ViewEngine来呈现数据.
但是在P5中,这个系统进行了较大的改进,增加了不少部分,使得扩展和管理更加方便了,当然,相应的,系统的复杂度也加大了.P5中关于ViewEngine的类图大致如下:
这个系统的执行流程大致如下:Mvc框架根据Routing中的数据找到相应的Controller(Controller实现了IController接口,且它不再管理ViewEngine),一个Controller包含一个IActionInvoker对象(将以前的ControllerActionInvoker接口化了),Controller中的Execute方法间接执行IActionInvoker的InvokeAction方法,系统默认的ActionInvoker将在该方法中间接执行Action,而每个Action会返回一个ActionResult,在P5中,系统自带了两种和ViewEngine有关的ActionResult,分别为: PartialViewResult和ViewResult,它们的继承关系可以见图,然后ViewResult会调用IViewEngine的FindPartialView或者FindView方法来获取对应的ViewEngineResult,最后调用ViewEngineResult中的IView的Render方法来呈现View.另外,系统中还有一个ViewEngines类来管理所有的ViewEngine,用户可以向ViewEngies中添加或者删除自己的ViewEngine.说到这儿可能有人觉得奇怪了,在这个执行流程中.没有任何地方说到ViewEngine的选择问题,如果系统有多个ViewEngine,系统怎么找到正确的ViewEngine并执行呢?其实,这只是系统将查找ViewEngine的工作交给了一个特殊的ViewEngine来完成,这就是CompositeViewEngine,它也就是ViewEngines.DefaultEngine这个特殊的ViewEngine中有一个ICollection<IViewEngine>对象,该对象实际上和ViewEngines中的ViewEngineCollection是同一对象,它的FindPartialView和FindView方法就是对系统目前所有的ViewEngine进行查找的方法,在每个PartialViewResult中,默认情况下会包含这个CompositeViewEngine对象.这样,使用这个ViewEngine呈现数据的时候实际上会间接查找系统中的所有ViewEngine,从而实现了在系统中ViewEngine的混合使用.另外值得一提的是,在CompositeViewEngine中,系统根据ViewName以及masterName查找的时候会返回第一个找到的ViewEngine,因此,在拥有多个ViewEngine的时候要注意加入的先后顺序.
在本篇中,我们探索了ViewEngine的工作模式以及新老版本的工作差异,下篇将实战自定义ViewEngine以及多ViewEngine的交互工作
本文作者: