最近剛好有要寫寄Email的程式,在代碼中寫HTML覺得很呆,抽出代碼外寫到txt或html檔當範本,由程式執行時在載入檔案時用Regex換關鍵字又覺得不夠好用,而且因為有時會有要判斷一些條件,就會寫一堆if esle在代碼中看了就討厭,因為寫MVC久了,就很希望範本也可以像MVC中的View,傳Model過去,在View層決定如何呈現,而更希望是使用Razor語法來寫範本,花了時間研究,找到RazorEngine,使用它來載入檔案,由它來編譯與執行並輸入結果。
RazorEngine
官網網址:http://razorengine.codeplex.com/
在找到RazorEngine之前曾經想過其他的方案,如T4與V8 Engine載jquery.template,但T4如果要獨立於MSBuild或Visual Studio執行有點麻煩,而V8 Engine我又不想在Class Library專案中放一堆js檔,後來就想到Razor,因為Razor的相關處理都是寫在System.Web.Razor,雖然Namespace叫System.Web,但根本沒有載入任何的System.Web相關的組件(如圖一),所以我肯定它可以獨立在非Web環境於中使用,在研究如何運用的期間,就發現早在去年就有人寫好放在CodePlex上,我太落伍了。

圖一 System.Web.Razor的參考,只有載入基本的三個組件
註:有興趣知道如何使用System.Web.Razor產生結果(基本上都是CodeDom),我所知道就有四套,小弟這一篇[ASP.NET MVC]Razor Views 預編譯(Pre-Compile)[1]-加快第一次執行回應速度介紹的二個Extension與本篇的RazorEngine與ASP.NET MVC 3使用的System.Web.WebPages.Razor,除了System.Web.WebPages.Razor外都是Open Source的可以下載Code來觀摩。
下面的範例,將展示如果只單獨使用System.Web.Razor.dll,如何產生結果(有點累,還是用別人的組件比較好)。
01 |
namespace RezorCodeDomSample
|
03 |
internal class Program
|
05 |
private static void Main(string[] args)
|
08 |
string template = @"@{var name=""Would"";}
|
11 |
var input = new System.IO.StringReader(template);
|
14 |
var host = new RazorEngineHost(new CSharpRazorCodeLanguage());
|
15 |
host.DefaultBaseClass = "RezorCodeDomSample.MyTemplate";
|
16 |
host.DefaultNamespace = "RezorCodeDomSample";
|
17 |
host.DefaultClassName = "MyTemplateResult";
|
18 |
var engine = new RazorTemplateEngine(host);
|
21 |
var code = engine.GenerateCode(input);
|
22 |
var codeType = code.GeneratedCode.Namespaces[0].Types[0];
|
23 |
var codeProvider = new CSharpCodeProvider();
|
33 |
var options = new CompilerParameters()
|
35 |
GenerateInMemory = true,
|
36 |
GenerateExecutable = false,
|
38 |
options.ReferencedAssemblies.Add(typeof(Program).Assembly.Location);
|
39 |
var asselby = codeProvider.CompileAssemblyFromDom(options, code.GeneratedCode);
|
42 |
var type = asselby.CompiledAssembly.GetType("RezorCodeDomSample.MyTemplateResult");
|
43 |
var ins = Activator.CreateInstance(type) as MyTemplate;
|
45 |
Console.Write(ins.Reault);
|
50 |
public class MyTemplate
|
52 |
private StringBuilder sb = new StringBuilder();
|
54 |
public virtual void Execute()
|
58 |
public void Write(object value)
|