熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

逃脫Asp.Net MVC框架

2022-06-13   來源: .NET編程 
    此文應該算Razor引擎淺析的續篇或者說淺析是此文的前傳
   
    為什麼要這麼做?
   
      AspNet MVC 其實也不是太好
   
    我有自己的敏捷Web框架 仍然想用Razor引擎
   
    動態編譯很有意思這也是將來的一個趨勢如果有人有興趣我倒是很想寫寫這方面的內容
   
    可是也有這些想法的人並不多找來找去這方面的資料和論述極其之少與其臨淵羨魚不如退而結網自己動手豐衣足食
   
    如Razor引擎淺析所述Razor的兩大主要功能模板文件和動態編譯器我們能不能單純就要而且只要這倆主要特性? 其它那些智能查找視圖文件等雖不能說是垃圾也是束縛手腳的條條框框我完全可以自己做失去的是一條繩索獲得是整個世界
   
    保持模板功能特別是設計時智能語法支持很簡單創建項目時選擇MVC項目然後把其它MVC相關的引用刪掉只剩下Razor就好了
   
    編譯? 你根本就找不到這一段代碼被淹沒在大量的輔助代碼中幸好我這裡已經找到了簡化修改之後就剩下了了幾行你就可以直接使用在甚至不必是Web項目中
   
    首先 用到的Razor域名空間
   
    [csharp] view plaincopy
   
    using SystemWebRazor;
   
    using SystemWebRazorGenerator;
   
    using SystemWebRazorParser;
   
    第一步動態編譯解析視圖文件生成代碼是的生成代碼Razor的語法可以說是私有語法需要先生成標准代碼然後才編譯生成我們熟悉的C#類Type需要注意的是我下面代碼用的模板基類是我自己的TeamplateBase後面會給出簡單實現當然好處就是靈活性你也可以直接用AspNet MVC的SystemWebMvcWebViewPage 不過我沒有試過也許會有其他問題不能保證
   
    [csharp]
   
    public static Type Compile<T>(string template_path)
   
    {
   
    //准備臨時類名讀取模板文件和Razor代碼生成器
   
    var class_name = c + GuidNewGuid()ToString(N
   
    var base_type = typeof(TemplateBase<>)MakeGenericType(typeof(T))
   
    var template = FileReadAllText(template_path)
   
    var host = new RazorEngineHost(new CSharpRazorCodeLanguage() () => new HtmlMarkupParser())
   
    {
   
    DefaultBaseClass = base_typeFullName
   
    DefaultClassName = class_name
   
    DefaultNamespace = YourNameSpacedynamic
   
    GeneratedClassContext =
   
    new GeneratedClassContext(Execute Write WriteLiteral WriteTo
   
    WriteLiteralTo
   
    YourNameSpaceTemplateBase
   
    };
   
    hostNamespaceImportsAdd(System
   
    hostNamespaceImportsAdd(YourNameSpaces
   
    //生成代碼
   
    CodeCompileUnit code;
   
    using (var reader = new StringReader(template)) {
   
    var generatedCode = new RazorTemplateEngine(host)GenerateCode(reader)
   
    code = generatedCodeGeneratedCode;
   
    }
   


    //准備編譯參數
   
    var @params = new CompilerParameters
   
    {
   
    IncludeDebugInformation = false
   
    TempFiles = new TempFileCollection(AppDomainCurrentDomainDynamicDirectory)
   
    CompilerOptions = /target:library /optimize
   
    GenerateInMemory = false
   
    };
   
    var assemblies = AppDomainCurrentDomain
   
    GetAssemblies()
   
    Where(a => !aIsDynamic)
   
    Select(a => aLocation)
   
    ToArray()
   
    @paramsReferencedAssembliesAddRange(assemblies)
   
    //編譯
   
    var provider = new CSharpCodeProvider()
   
    var compiled = providerCompileAssemblyFromDom(@params code)
   
    if (compiledErrorsCount > ) {
   
    var compileErrors = stringJoin(\r\n compiledErrorsCast<object>()Select(o => oToString()))
   
    throw new ApplicationException(Failed to compile Razor: + compileErrors)
   
    }
   
    //編譯成功後 返回編譯後的動態Type
   
    return compiledCompiledAssemblyGetType(SkightArchPresentationWebCoreViewEnginsRazordynamic + class_name)
   
    }
   
    第二步就簡單多了就和任何靜態類一樣用反射創建實例然後復制Model對象執行模板最後輸出結果是就自動吧Model類的數據嵌入了
   
    [csharp]
   
    public static string Render<T>(T modelstring template_path)
   
    {
   
    var type = Compile<T>(template_path)
   
    //創建視圖實例
   
    var instance = (TemplateBase<T>)ActivatorCreateInstance(type)
   
    //執行模板(把數據嵌入文件)
   
    instanceModel = model;
   
    instanceExecute()
   
    //輸出最終結果
   
    var result = instanceResult;
   
    return result;
   
    }
   
    最後看看視圖模板類一個基類和一個泛型基類後者用於前類型Model
   


    [csharp]
   
    public abstract class TemplateBase
   
    {
   
    public string Layout { get; set; }
   
    public UrlHelper Url { get; set; }
   
    public Func<string> RenderBody { get; set; }
   
    public string Path { get; internal set; }
   
    public string Result { get { return WriterToString() } }
   
    protected TemplateBase()
   
    {
   
    }
   
    public TextWriter Writer
   
    {
   
    get
   
    {
   
    if(writer==null)
   
    {writer = new StringWriter()
   
    }
   
    return writer;
   
    }
   
    set {
   
    writer = value;
   
    }
   
    }
   
    private TextWriter writer;
   
    public void Clear() {
   
    WriterFlush()
   
    }
   
    public virtual void Execute() { }
   
    public void Write(object @object) {
   
    if (@object == null) {
   
    return;
   
    }
   
    WriterWrite(@object)
   
    }
   
    public void WriteLiteral(string @string) {
   
    if (@string == null) {
   
    return;
   
    }
   
    WriterWrite(@string)
   
    }
   
    public static void WriteLiteralTo(TextWriter writer string literal) {
   
    if (literal == null) {
   
    return;
   
    }
   
    writerWrite(literal)
   
    }
   
    public static void WriteTo(TextWriter writer object obj) {
   
    if (obj == null) {
   
    return;
   
    }
   
    writerWrite(obj)
   
    }
   
    }
   
    public abstract class TemplateBase<T> :TemplateBase
   
    {
   
    public T Model { get; set; }
   
    }


From:http://tw.wingwit.com/Article/program/net/201311/12710.html
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.