Use razor in ASP. net mvc to customize the view engine framework (2)

Source: Internet
Author: User

ASP. NET mvc3 began to use razor as its view engine, replacing the original ASP. NET web form engine. I recently studied the implementation of razor in mvc3, and found a starting point to allow us to customize the view parsing Engine Based on razor syntax. It can be used in projects, such as mail template customization. Currently, it is only a demo version and is still being improved. Codeplex: http://codeof.codeplex.com/SourceControl/list/changesets where razorex

Currently supported functions:

1. Support for Razor syntax (Basic @ syntax) Template File Parsing
2. Support layout/renderbody syntax
3. Support dynamic compilation mechanism similar to Asp.net, inProgramDuring running, if the template file changes, you do not need to re-compile it.
4. Support namespace reference configuration
5. Support complex assembly reference relationships

In the implementation of ASP. net mvc using razor, the custom view engine framework (1) describes how to use Microsoft to implementSystem. Web. RazorTo parse the template based on the razor syntax, and finally get a compilation unit or source code. This article describes howCodeDynamically compile and execute the compilation unit or source code.

It should not be more flexible than dynamic compilation. It allows us to dynamically create program code and compile and execute it. Despite its flexibility, the implementation is complicated and inefficient, so you should not consider it unless necessary. In this case, we have to use this method, because the template is created by the user, and we can never predict it:

In. net,System. codedom. compiler. codedomproviderProvides methods to compile one or more source programs or compilation units into an assembly. In. net4.0Microsoft. CSHARP. csharpcodeproviderThe class is inherited and implemented. WithCsharpcodeproviderIt is very easy to compile a dynamic assembly:

 
Csharpcodeprovider provider = new csharpcodeprovider (); compilerparameters c_options = new compilerparameters (); Parameters = false; c_options.generateexecutable = false; c_options.generateinmemory = true; Role ("system. DLL "); compilerresults Results = provider. compileassemblyfromsource (c_options, Code );

The code snippet above instantiatesCsharpcodeproviderAndCompilerparameters. The former is used for compilation, and the latter is used to specify some options during compilation, such as the Code settings above. Last callCompileassemblyfromsource, Input the compilation options andSource codeText. In additionCsharpcodeproviderOfCompileassemblyfromdomHeavy Load, can accept the compilation option object and

CodecompileunitObject as a parameter. In the previous article, we know thatRazortemplateengine. generatecodeThe method returns exactly includeCodecompileunitSo we will useCompileassemblyfromdom Method.

In the return valueCompilerresults. compiledassembly, We can access the Assembly object of the compilation result, and then execute the compilation code with reflection. In addition, during the compilation process, if the compilation fails, an exception is thrown.

In the engine development process, apart from the basic content that needs to be known in the previous article and above, the following problems need to be solved:

1. The DLL to be referenced must be known during dynamic compilation; otherwise, the compilation will fail.For example, I reference a complex object in the template. This object definition is obviously not in the engine's assembly. It may be your own assembly or the Assembly referenced by your assembly. This raises a question: how do we know which assembly to reference during compilation? I used a stupid solution: Starting from getcallingassembly, I traversed the dependent assembly and referenced it all at compile time. In the codeAssemblyreferenceresolverThis function is implemented;

2. For the above problem, the source code must be referenced with a correct namespace during compilation. Otherwise, the compilation will fail even if the referenced assembly is still successful.To this end, the MVC implementation is imitated, a configuration is designed, and the following configuration file can be added:

<Configuration> <configsections> <section name = "razortemplateengineimportnamespace" type = "razortemplateengine. importnamespaceresolver, razortemplateengine "/> </configsections> <razortemplateengineimportnamespace> <add namespace =" modeltest "/> <add namespace =" system. collections. generic "/> </razortemplateengineimportnamespace> </configuration>

3. A template corresponds to a class, which corresponds to an assembly. If the parsing template is repeatedly compiled, the efficiency will be greatly affected.The solution is to use cache: Save the compiled DLL and template files into a dictionary. If you have already compiled and the last update time of the template file is not later than the DLL creation time, the compiled assembly is directly returned; otherwise, the compilation is performed. In the codeDynamicassemblycacheClass to implement this function;

4. How to Implement template nesting.Add the following attributes and methods to the base class _ 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 ;}

In this way, the syntax similar to layout = "@ renderbody can be compiled. It can be implemented with recursive execute.

 

 

The project now implements basic functions. I plan to release a version after a trial period. The source code is not much code on the above codeplex and remains to be reconstructed. If you are interested, you can discuss it with me and hope to implement a robust engine.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.