Razor Parser that parses a razor template, generate c# class on the fly, executes the assembly and returns output string.
Another excellent post can be found here. http://www.fidelitydesign.net/?p=208
Another excellent post can be found here. http://www.fidelitydesign.net/?p=208
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Web.Razor;
using System.Web.Razor.Generator;
using System.Web.Razor.Parser;
using System.Web.Razor.Text;
using System.IO;
using System.Text.RegularExpressions;
using System.Diagnostics;
using Microsoft.VisualBasic;
using Microsoft.CSharp;
using RazorEngine.Templating;
namespace RazorLibrary
{
public class Razor
{
public string
GetRazorOutput(string template, T
model)
{
Type modelType = typeof(T); // Get type of
model
var codeDom = new CSharpCodeProvider(); //
Will be used to generate source code on the fly and compile the assembly
//Generate a razor class generator where class name is
GeneratorClass with Namespace Razor.Dynamic
CSharpRazorCodeGenerator generator = new CSharpRazorCodeGenerator("GeneratorClass", "Razor.Dynamic", null, new RazorEngineHost(new CSharpRazorCodeLanguage()));
// Will be used to Parse Razor template
var parser = new RazorParser(new CSharpCodeParser(), new
HtmlMarkupParser()); // Razor Parser with C# and Html
// Razor requires clear, execute, write and WriteLiteral
methods which are defined in TemplateBase
Type baseType = (modelType == null) ? typeof(TemplateBase) : typeof(TemplateBase<>).MakeGenericType(modelType);
// Add base class to the generated class i.e. public class
GeneratorClass :
RazorLibrary.TemplateBase>
generator.GeneratedClass.BaseTypes.Add(baseType);
using (var reader = new StreamReader(new MemoryStream(Encoding.ASCII.GetBytes(template))))
{
parser.Parse(reader, generator); //
reader:Input stream and generator:visitor Pattern
}
var builder = new StringBuilder();
using (var writer = new StringWriter(builder))
{
// Generate source code into writer, using
code generator
codeDom.GenerateCodeFromCompileUnit(generator.GeneratedCode, writer, new CodeGeneratorOptions());
}
var
@params = new CompilerParameters();
foreach
(var assembly in
AppDomain.CurrentDomain.GetAssemblies())
{
@params.ReferencedAssemblies.Add(assembly.Location);
}
//The
call to CompileAssemblyFromSource is where the assembly gets compiled. This
method takes the parameters object and the source code, which is a string
var
result = codeDom.CompileAssemblyFromSource(@params, new[]
{ builder.ToString() });
if
(result.Errors != null &&
result.Errors.Count > 0)
throw
new Exception("Error in compilation."); // This can be made better by creating custom exceptions
handler to traverse the errors collection
// Create
an instance of Razor.Dynamic.GeneratorClass
ITemplate
instance = (ITemplate)result.CompiledAssembly.CreateInstance("Razor.Dynamic.GeneratorClass");
var
Templates = new Dictionary<string, ITemplate>();
if
(instance is ITemplate)
((ITemplate)instance).Model
= model;
instance.Execute();
return
instance.Result;
}
}
}
No comments:
Post a Comment