热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

利用Razor在ASP.NETMVC中的实现,自定义视图引擎框架(2)

ASP.NETMVC3开始使用Razor作为其视图引擎,取代了原来ASP.NETWebForm引擎。笔者最近研究了一下MVC3对Razor的实现,从中找

ASP.NET MVC3开始使用Razor作为其视图引擎,取代了原来ASP.NET Web Form引擎。笔者最近研究了一下MVC3对Razor的实现,从中找到一个切入点,能够让我们自定义基于Razor语法的视图解析引擎。在项目里面可以用于诸如邮件模板定制等方面。目前,只是一个demo版本,还在进一步完善中。CodePlex : http://codeof.codeplex.com/SourceControl/list/changesets 其中的RazorEx

目前支持的功能:

1.支持Razor语法(基本的@语法)的模板文件解析
2.支持Layout / Renderbody语法
3.支持类似asp.net 动态编译机制,在程序运行期间,如果模板文件变了,无需重新编译
4.支持名字空间引用配置
5.支持复杂的程序集引用关系

在利用Razor在ASP.NET MVC中的实现,自定义视图引擎框架(1)中,介绍了如何利用微软实现的System.Web.Razor来解析基于Razor语法的模板,最后得到一个编译单元或者源码。本文介绍如何在代码中对编译单元或者源码进行动态编译,并执行。

应该没有比动态编译更灵活的了,它允许我们动态的创建程序代码并编译执行。尽管它灵活,但是实现复杂,并且效率不高,不到万不得已不要考虑。而在这个case中却不得不用这种方式,因为模板是用户创建的,我们永远不可能预知:

image

在.net中,System.CodeDom.Compiler.CodeDomProvider提供了将一个或多个源程序或编译单元编译成程序集的方法。在.net4.0中Microsoft.CSharp.CSharpCodeProvider继承了上面这个类,并给予了实现。有了CSharpCodeProvider,编译一个动态的程序集十分容易:

CSharpCodeProvider provider = new CSharpCodeProvider();CompilerParameters c_options = new CompilerParameters();c_options.IncludeDebugInformation = false;c_options.GenerateExecutable = false;c_options.GenerateInMemory = true;c_options.ReferencedAssemblies.Add( "System.dll" );CompilerResults results = provider.CompileAssemblyFromSource(c_options, code);

上面的代码段,实例化了一个CSharpCodeProvider以及一个CompilerParameters。前者用于编译,后者用于指定编译时的一些选项,如上面的代码的设置。最后调用CompileAssemblyFromSource,传入编译选项和源代码文本即可。另外CSharpCodeProviderCompileAssemblyFromDom重载,可以接受编译选项对象和

CodeCompileUnit对象作为参数。在上一篇中,我们知道RazorTemplateEngine.GenerateCode方法返回的刚好是包含了CodeCompileUnit的对象,所以我们将使用CompileAssemblyFromDom方法

在返回值CompilerResults.CompiledAssembly中,我们可以访问到编译结果的Assembly对象,再结合反射即可执行编译代码。另外,在编译过程中,如果编译失败将抛出异常。

在引擎的开发过程中,除了上一篇和上述需要知道的基本内容外,分别有以下问题需要解决:

1、动态编译时需要知道引用哪些dll,否则将无法编译成功。比如在模板里面我引用了一个复杂对象,这个对象定义显然不在引擎的程序集中,可能是用户自己的程序集,或是用户程序集引用的程序集。这就带来了一个问题,在编译时我们如何知道要引用哪些程序集?我用了一个比较笨的方案:从GetCallingAssembly开始,把相互依赖的程序集遍历一遍,并且全部在编译时引用。代码中的AssemblyReferenceResolver就实现了这个功能;

2、如上面的问题,编译的时候,源码需要有正确的命名空间的引用,否则即使引用的程序集,还是不能编译成功。为此,模仿mvc的实现,设计了一个configuration,添加下面这样的配置文件即可:


3、一个模板对应一个类,也就对应一个程序集,如果反复解析模板会反复编译,这样会很大程度上影响效率。解决方案是使用缓存:将编译过的dll和模板文件存成字典,如果已经编译过了并且模板文件的最后更新时间不晚于dll的创建时间,则直接返回之前编译的程序集;否则就进行编译。代码中的DynamicAssemblyCache类就实现这个功能;

4、如何实现模板嵌套。在基类__TemplatePage中加入下面属性和方法:

private string _layout;public virtual string Layout {get { return _layout; }set {_layout = value;}}public string ChildBody { get; set; }public virtual string RenderBody(){if(ChildBody != null)return ChildBody;return string.Empty;}

这样类似Layout=””  @RenderBody的语法就可以通过编译。配合递归的Execute即可实现。

 

 

项目现已实现基本的功能,我打算过一段试用期过后Release一个版本。源码在上面的CodePlex上,代码不多,还有待重构,有兴趣的同仁可以和我讨论,希望能实现一个健壮的引擎。

转:https://www.cnblogs.com/P_Chou/archive/2011/08/30/customize-razor-template-2.html



推荐阅读
  • 本文以 www.域名.com 为例,详细介绍如何为每个注册用户提供独立的二级域名,如 abc.域名.com。实现这一功能的核心步骤包括:首先,确保域名支持泛解析,即将 A 记录设置为 *.域名.com,以便将所有二级域名请求指向同一服务器。接着,在服务器端使用 ASP.NET 2.0 进行配置,通过解析 HTTP 请求中的主机头信息,动态识别并处理不同的二级域名,从而实现个性化内容展示。此外,还需在数据库中维护用户与二级域名的对应关系,确保每个用户的二级域名都能正确映射到其专属内容。 ... [详细]
  • 基于Net Core 3.0与Web API的前后端分离开发:Vue.js在前端的应用
    本文介绍了如何使用Net Core 3.0和Web API进行前后端分离开发,并重点探讨了Vue.js在前端的应用。后端采用MySQL数据库和EF Core框架进行数据操作,开发环境为Windows 10和Visual Studio 2019,MySQL服务器版本为8.0.16。文章详细描述了API项目的创建过程、启动步骤以及必要的插件安装,为开发者提供了一套完整的开发指南。 ... [详细]
  • Ext JS MVC系列一:环境搭建与框架概览
    本文主要介绍了如何在项目中使用Ext JS 4作为前端框架,并详细讲解了Ext JS 4的MVC开发模式。文章将从项目目录结构、相关CSS和JS文件的引用以及MVC框架的整体认识三个方面进行总结。 ... [详细]
  • Framework7:构建跨平台移动应用的高效框架
    Framework7 是一个开源免费的框架,适用于开发混合移动应用(原生与HTML混合)或iOS&Android风格的Web应用。此外,它还可以作为原型开发工具,帮助开发者快速创建应用原型。 ... [详细]
  • 本文总结了一些开发中常见的问题及其解决方案,包括特性过滤器的使用、NuGet程序集版本冲突、线程存储、溢出检查、ThreadPool的最大线程数设置、Redis使用中的问题以及Task.Result和Task.GetAwaiter().GetResult()的区别。 ... [详细]
  • 深入解析Struts、Spring与Hibernate三大框架的面试要点与技巧 ... [详细]
  • 本文详细解析了使用C++实现的键盘输入记录程序的源代码,该程序在Windows应用程序开发中具有很高的实用价值。键盘记录功能不仅在远程控制软件中广泛应用,还为开发者提供了强大的调试和监控工具。通过具体实例,本文深入探讨了C++键盘记录程序的设计与实现,适合需要相关技术的开发者参考。 ... [详细]
  • Spring框架中枚举参数的正确使用方法与技巧
    本文详细阐述了在Spring Boot框架中正确使用枚举参数的方法与技巧,旨在帮助开发者更高效地掌握和应用枚举类型的数据传递,适合对Spring Boot感兴趣的读者深入学习。 ... [详细]
  • ### 优化后的摘要本学习指南旨在帮助读者全面掌握 Bootstrap 前端框架的核心知识点与实战技巧。内容涵盖基础入门、核心功能和高级应用。第一章通过一个简单的“Hello World”示例,介绍 Bootstrap 的基本用法和快速上手方法。第二章深入探讨 Bootstrap 与 JSP 集成的细节,揭示两者结合的优势和应用场景。第三章则进一步讲解 Bootstrap 的高级特性,如响应式设计和组件定制,为开发者提供全方位的技术支持。 ... [详细]
  • Web开发框架概览:Java与JavaScript技术及框架综述
    Web开发涉及服务器端和客户端的协同工作。在服务器端,Java是一种优秀的编程语言,适用于构建各种功能模块,如通过Servlet实现特定服务。客户端则主要依赖HTML进行内容展示,同时借助JavaScript增强交互性和动态效果。此外,现代Web开发还广泛使用各种框架和库,如Spring Boot、React和Vue.js,以提高开发效率和应用性能。 ... [详细]
  • 本文详细介绍了在 CentOS 7 系统中配置 fstab 文件以实现开机自动挂载 NFS 共享目录的方法,并解决了常见的配置失败问题。 ... [详细]
  • 本文详细探讨了几种常用的Java后端开发框架组合及其具体应用场景。通过对比分析Spring Boot、MyBatis、Hibernate等框架的特点和优势,结合实际项目需求,为开发者提供了选择合适框架组合的参考依据。同时,文章还介绍了这些框架在微服务架构中的应用,帮助读者更好地理解和运用这些技术。 ... [详细]
  • 在现代Web开发中,许多网站采用伪静态技术,如URL以.html或.shtml结尾,以提升用户体验和搜索引擎优化。MVC框架中的路由机制能够轻松实现这一功能。通过配置默认路由并添加伪静态路由规则,MVC框架按照从上到下的顺序进行路由匹配,确保请求被正确处理。此外,这种机制还支持灵活的自定义路由,进一步增强了应用的可扩展性和维护性。 ... [详细]
  • 如何撰写适应变化的高效代码:策略与实践
    编写高质量且适应变化的代码是每位程序员的追求。优质代码的关键在于其可维护性和可扩展性。本文将从面向对象编程的角度出发,探讨实现这一目标的具体策略与实践方法,帮助开发者提升代码效率和灵活性。 ... [详细]
  • 通过利用代码自动生成技术,旨在减轻软件开发的复杂性,缩短项目周期,减少冗余代码的编写,从而显著提升开发效率。该方法不仅能够降低开发人员的工作强度,还能确保代码的一致性和质量。 ... [详细]
author-avatar
梦晗明镜百_576
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有