Welcome 微信登录

首页 / 网页编程 / ASP.NET / ASP.NET MVC的Razor引擎:RazorView

ASP.NET MVC的Razor引擎:RazorView2012-09-07 博客园 ArtechRazor引擎具有两个核心的类型,一个是表示View本身的类型RazorView,另一个则是获取和创建它的RazorViewEngine,我们将用两篇文章对它们分别进行剖析。Razor引擎下的View通过类型RazorView表示,它与表示Web Form引擎View的类型WebFormView都是BuildManagerCompiledView的子类。

一、BuildManagerCompiledView

为了能够清楚地说明实现在BuildManagerCompiledView中的View激活与呈现机制,我们列出了BuildManagerCompiledView中与此相关的内部和受保护的成员。

 1: public abstract class BuildManagerCompiledView : IView
2: {
3: internal IViewPageActivator ViewPageActivator;
4:
5: protected BuildManagerCompiledView(ControllerContext controllerContext, string viewPath);
6: protected BuildManagerCompiledView(ControllerContext controllerContext, string viewPath, IViewPageActivator viewPageActivator);
7: internal BuildManagerCompiledView(ControllerContext controllerContext, string viewPath, IViewPageActivator viewPageActivator, IDependencyResolver dependencyResolver);
8:
9: public void Render(ViewContext viewContext, TextWriter writer);
10: protected abstract void RenderView(ViewContext viewContext, TextWriter writer, object instance);
11:
12: internal IBuildManager BuildManager { get; set; }
13: public stringViewPath { get; protected set; }
14: }
通过《View编译原理》的介绍我们知道采用Razor引擎的View文件(.cshtml或者.vbhtml)最终都会编译成一个WebViewPage类型,所以通过RazorView/WebFormView体现的View的呈现机制最终体现在对WebViewPage对象的激活。我们可以利用BuildManager根据View文件的虚拟路径得到编译后的类型。从名称也可以看出来,BuildManagerCompiledView内部就是利用了BuildManager根据指定的View文件虚拟路径完成对WebViewPage对象激活。

BuildManagerCompiledView的属性ViewPath表示的就是View文件的虚拟路径,该属性在构造函数中被初始化。BuildManagerCompiledView具有三个构造函数,对象本身的构造逻辑体现在内部构造函数上。如上面的代码片断所示,除了将当前ControllerContext和View文件虚拟路径作为构造函数的参数之外,该构造函数还具有额外两个参数,其类型分别是IViewPageActivator和IDependencyResolver。

 1: public interface IViewPageActivator
2: {
3: object Create(ControllerContext controllerContext, Type type);
4: }
上面的代码片断体现了接口IViewPageActivator的定义。顾名思义,该接口旨在实现对WebViewPage对象的激活,基于类型的对象激活机制实现在Create方法中。BuildManagerCompiledView的构造函数中指定的ViewPageActivator被用于初始化内部字段ViewPageActivator,如果没有通过构造函数显式指定ViewPageActivator对象,默认采用的是一个DefaultViewPageActivator对象。

DefaultViewPageActivator是一个具有如下定义的内部类型,我们可以看到它实际上依赖于一个DependencyResolver对象完成针对WebViewPage对象的激活。这个DependencyResolver对象可以通过构造函数进行显式设置,而默认使用的DependencyResolver对象来源于DependencyResolver类型的静态属性Current。

 1: internal class DefaultViewPageActivator : IViewPageActivator
2: {
3: private Func<IDependencyResolver> _resolverThunk;
4: public DefaultViewPageActivator() : this(null)
5: {}
6: 
7: public DefaultViewPageActivator(IDependencyResolver resolver)
8: {
9: Func<IDependencyResolver> func = null;
10: if (resolver == null)
11: {
12: this._resolverThunk = () => DependencyResolver.Current;
13: }
14: else
15: {
16: if (func == null)
17: {
18: func = () => resolver;
19: }
20: this._resolverThunk = func;
21: }
22: }
23: 
24: public object Create(ControllerContext controllerContext, Type type)
25: {
26: return (this._resolverThunk().GetService(type) ?? Activator.CreateInstance(type));
27: }
28: }