婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > 詳細介紹.NET中的動態編譯技術

詳細介紹.NET中的動態編譯技術

熱門標簽:廣州銷售外呼系統定制 400電話辦理信任翰諾科技 福州人工智能電銷機器人加盟 ai電銷機器人對貸款有幫助嗎 怎樣給陜西地圖標注顏色 地圖標注多少錢一張 電銷機器人 數據 云狐人工智能電話機器人 宿遷智能外呼系統排名

代碼的動態編譯并執行是一個.NET平臺提供給我們的很強大的工具用以靈活擴展(當然是面對內部開發人員)復雜而無法估算的邏輯,并通過一些額外的代碼來擴展我們已有 的應用程序。這在很大程度上給我們提供了另外一種擴展的方式(當然這并不能算是嚴格意義上的擴展,但至少為我們提供了一種思路)。

動態代碼執行可以應用在諸如模板生成,外加邏輯擴展等一些場合。一個簡單的例子,為了網站那的響應速度,HTML靜態頁面往往是我們最好的選擇,但基于數據驅動的網站往往又很難用靜態頁面實現,那么將動態頁面生成html的工作或許就是一個很好的應用場合。另外,對于一些模板的套用,我們同樣可以用它來做。另外這本身也是插件編寫的方式。

最基本的動態編譯

.Net為我們提供了很強大的支持來實現這一切我們可以去做的基礎,主要應用的兩個命名空間是:System.CodeDom.Compiler和Microsoft.CSharp或Microsoft.VisualBasic。另外還需要用到反射來動態執行你的代碼。動態編譯并執行代碼的原理其實在于將提供的源代碼交予CSharpCodeProvider來執行編譯(其實和CSC沒什么兩樣),如果沒有任何編譯錯誤,生成的IL代碼會被編譯成DLL存放于于內存并加載在某個應用程序域(默認為當前)內并通過反射的方式來調用其某個方法或者觸發某個事件等。之所以說它是插件編寫的一種方式也正是因為與此,我們可以通過預先定義好的借口來組織和擴展我們的程序并將其交還給主程序去觸發。一個基本的動態編譯并執行代碼的步驟包括:

·         將要被編譯和執行的代碼讀入并以字符串方式保存

·         聲明CSharpCodeProvider對象實例

·         調用CSharpCodeProvider實例的CompileAssemblyFromSource方法編譯

·         用反射生成被生成對象的實例(Assembly.CreateInstance)

·         調用其方法

以下代碼片段包含了完整的編譯和執行過程:

復制代碼 代碼如下:

//get the code to compile

string strSourceCode = this.txtSource.Text;

 

// 1.Create a new CSharpCodePrivoder instance

CSharpCodeProvider objCSharpCodePrivoder = new CSharpCodeProvider();

 

// 2.Sets the runtime compiling parameters by crating a new CompilerParameters instance

CompilerParameters objCompilerParameters = new CompilerParameters();

objCompilerParameters.ReferencedAssemblies.Add("System.dll");

objCompilerParameters.ReferencedAssemblies.Add("System.Windows.Forms.dll");

objCompilerParameters.GenerateInMemory = true;

 

// 3.CompilerResults: Complile the code snippet by calling a method from the provider

CompilerResults cr = objCSharpCodePrivoder.CompileAssemblyFromSource(objCompilerParameters, strSourceCode);

 

if (cr.Errors.HasErrors)

{

    string strErrorMsg = cr.Errors.Count.ToString() + " Errors:";

 

    for (int x = 0; x cr.Errors.Count; x++)

    {

        strErrorMsg = strErrorMsg + "\r\nLine: " +

                     cr.Errors[x].Line.ToString() + " - " +

                     cr.Errors[x].ErrorText;

    }

 

    this.txtResult.Text = strErrorMsg;

    MessageBox.Show("There were build erros, please modify your code.", "Compiling Error");

 

    return;

}

 

// 4. Invoke the method by using Reflection

Assembly objAssembly = cr.CompiledAssembly;

object objClass = objAssembly.CreateInstance("Dynamicly.HelloWorld");

if (objClass == null)

{

    this.txtResult.Text = "Error: " + "Couldn't load class.";

    return;

}

 

object[] objCodeParms = new object[1];

objCodeParms[0] = "Allan.";

 

string strResult = (string)objClass.GetType().InvokeMember(

           "GetTime", BindingFlags.InvokeMethod, null, objClass, objCodeParms);

 

this.txtResult.Text = strResult;

需要解釋的是,這里我們在傳遞編譯參數時設置了GenerateInMemory為true,這表明生成的DLL會被加載在內存中(隨后被默認引用入當前應用程序域)。在調用GetTime方法時我們需要加入參數,傳遞object類型的數組并通過Reflection的InvokeMember來調用。在創建生成的Assembly中的對象實例時,需要注意用到的命名空間是你輸入代碼的真實命名空間。以下是我們輸入的測試代碼(為了方便,所有的代碼都在外部輸入,動態執行時不做調整):

復制代碼 代碼如下:

using System;

namespace Dynamicly

{

    public class HelloWorld

    {

        public string GetTime(string strName)

        {

            return  "Welcome " + strName + ", Check in at " + System.DateTime.Now.ToString();

        }

    }

}

運行附件中提供的程序,可以很容易得到一下結果:

改進的執行過程

現在一切看起來很好,我們可以編譯代碼并把代碼加載到當前應用程序域中來參與我們的活動,但你是否想過去卸載掉這段程序呢?更好的去控制程序呢?另外,當你運行這個程序很多遍的時候,你會發現占用內存很大,而且每次執行都會增大內存使用。是否需要來解決這個問題呢?當然需要,否則你會發現這個東西根本沒用,我需要執行的一些大的應用會讓我的服務器crzay,不堪重負而瘋掉的。

要解決這個問題我們需要來了解一下應用程序域。.NET Application Domain是.NET提供的運行和承載一個活動的進程(Process)的容器,它將這個進程運行所需的代碼和數據,隔離到一個小的范圍內,稱為Application Domain。當一個應用程序運行時,Application Domains將所有的程序集/組件集加載到當前的應用程序域中,并根據需要來調用。而對于動態生成的代碼/程序集,我們看起來好像并沒有辦法去管理它。其實不然,我們可以用Application Domain提供的管理程序集的辦法來動態加載和移除Assemblies來達到我們的提高性能的目的。具體怎么做呢,在前邊的基礎上增加以下步驟:

·         創建另外一個Application Domain

·         動態創建(編譯)代碼并保存到磁盤

·         創建一個公共的遠程調用接口

·         創建遠程調用接口的實例。并通過這個接口來訪問其方法。

換句話來講就是將對象加載到另外一個AppDomain中并通過遠程調用的方法來調用。所謂遠程調用其實也就是跨應用程序域調用,所以這個對象(動態代碼)必須繼承于MarshalByRefObject類。為了復用,這個接口被單獨提到一個工程中,并提供一個工廠來簡化每次的調用操作:

復制代碼 代碼如下:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Reflection;

 

namespace RemoteAccess

{

    /// summary>

          /// Interface that can be run over the remote AppDomain boundary.

          /// /summary>

          public interface IRemoteInterface

          {

                   object Invoke(string lcMethod,object[] Parameters);

          }

 

          /// summary>

          /// Factory class to create objects exposing IRemoteInterface

          /// /summary>

          public class RemoteLoaderFactory : MarshalByRefObject

          {

                   private const BindingFlags bfi = BindingFlags.Instance | BindingFlags.Public | BindingFlags.CreateInstance;

 

                   public RemoteLoaderFactory() {}

 

                   public IRemoteInterface Create( string assemblyFile, string typeName, object[] constructArgs )

                   {

                             return (IRemoteInterface) Activator.CreateInstanceFrom(

                                      assemblyFile, typeName, false, bfi, null, constructArgs,

                                      null, null, null ).Unwrap();

                   }

          }      

}

接下來在原來基礎上需要修改的是:

·         將編譯成的DLL保存到磁盤中。

·         創建另外的AppDomain。

·         獲得IRemoteInterface接口的引用。(將生成的DLL加載到額外的AppDomain)

·         調用InvokeMethod方法來遠程調用。

·         可以通過AppDomain.Unload()方法卸載程序集。

以下是完整的代碼,演示了如何應用這一方案。

復制代碼 代碼如下:

//get the code to compile

string strSourceCode = this.txtSource.Text;

 

//1. Create an addtional AppDomain

AppDomainSetup objSetup = new AppDomainSetup();

objSetup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;

AppDomain objAppDomain = AppDomain.CreateDomain("MyAppDomain", null, objSetup);

 

// 1.Create a new CSharpCodePrivoder instance

CSharpCodeProvider objCSharpCodePrivoder = new CSharpCodeProvider();

 

// 2.Sets the runtime compiling parameters by crating a new CompilerParameters instance

CompilerParameters objCompilerParameters = new CompilerParameters();

objCompilerParameters.ReferencedAssemblies.Add("System.dll");

objCompilerParameters.ReferencedAssemblies.Add("System.Windows.Forms.dll");

 

// Load the remote loader interface

objCompilerParameters.ReferencedAssemblies.Add("RemoteAccess.dll");

 

// Load the resulting assembly into memory

objCompilerParameters.GenerateInMemory = false;

objCompilerParameters.OutputAssembly = "DynamicalCode.dll";

 

// 3.CompilerResults: Complile the code snippet by calling a method from the provider

CompilerResults cr = objCSharpCodePrivoder.CompileAssemblyFromSource(objCompilerParameters, strSourceCode);

 

if (cr.Errors.HasErrors)

{

    string strErrorMsg = cr.Errors.Count.ToString() + " Errors:";

 

    for (int x = 0; x cr.Errors.Count; x++)

    {

        strErrorMsg = strErrorMsg + "\r\nLine: " +

                     cr.Errors[x].Line.ToString() + " - " +

                     cr.Errors[x].ErrorText;

    }

 

    this.txtResult.Text = strErrorMsg;

    MessageBox.Show("There were build erros, please modify your code.", "Compiling Error");

 

    return;

}

 

// 4. Invoke the method by using Reflection

RemoteLoaderFactory factory = (RemoteLoaderFactory)objAppDomain.CreateInstance("RemoteAccess","RemoteAccess.RemoteLoaderFactory").Unwrap();

 

// with help of factory, create a real 'LiveClass' instance

object objObject = factory.Create("DynamicalCode.dll", "Dynamicly.HelloWorld", null);

 

if (objObject == null)

{

    this.txtResult.Text = "Error: " + "Couldn't load class.";

    return;

}

 

// *** Cast object to remote interface, avoid loading type info

IRemoteInterface objRemote = (IRemoteInterface)objObject;

 

object[] objCodeParms = new object[1];

objCodeParms[0] = "Allan.";

 

string strResult = (string)objRemote.Invoke("GetTime", objCodeParms);

 

this.txtResult.Text = strResult;

 

//Dispose the objects and unload the generated DLLs.

objRemote = null;

AppDomain.Unload(objAppDomain);

 

System.IO.File.Delete("DynamicalCode.dll");

對于客戶端的輸入程序,我們需要繼承于MarshalByRefObject類和IRemoteInterface接口,并添加對RemoteAccess程序集的引用。以下為輸入:

復制代碼 代碼如下:

using System;

using System.Reflection;

using RemoteAccess;

 

namespace Dynamicly

{

    public class HelloWorld : MarshalByRefObject,IRemoteInterface

    {

        public object Invoke(string strMethod,object[] Parameters)

        {

            return this.GetType().InvokeMember(strMethod, BindingFlags.InvokeMethod,null,this,Parameters);

        }

 

        public string GetTime(string strName)

        {

            return  "Welcome " + strName + ", Check in at " + System.DateTime.Now.ToString();

        }

    }

}


這樣,你可以通過適時的編譯,加載和卸載程序集來保證你的程序始終處于一個可控消耗的過程,并且達到了動態編譯的目的,而且因為在不同的應用程序域中,讓你的本身的程序更加安全和健壯。
示例代碼下載:http://xiazai.jb51.net/201311/yuanma/DynamicCompiler(jb51.net).rar

您可能感興趣的文章:
  • .NET的動態編譯與WS服務調用詳解
  • 使用 C# 動態編譯代碼和執行的代碼
  • C# 動態編譯、動態執行、動態調試
  • .NET 動態編譯
  • c#動態編譯執行對象方法示例 運用映射機制創建對象

標簽:新疆 曲靖 延安 黃南 綿陽 焦作 宜春 大興安嶺

巨人網絡通訊聲明:本文標題《詳細介紹.NET中的動態編譯技術》,本文關鍵詞  詳細,介紹,.NET,中的,動態,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《詳細介紹.NET中的動態編譯技術》相關的同類信息!
  • 本頁收集關于詳細介紹.NET中的動態編譯技術的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    成人在线视频一区| 在线观看日韩毛片| 人妖欧美一区二区| 国产在线精品一区二区不卡了 | 亚洲欧洲另类国产综合| 日韩码欧中文字| 亚洲一区二区五区| 高清av一区二区| 欧美日韩视频在线观看一区二区三区| 欧美电影免费提供在线观看| 亚洲视频在线一区| 九九视频精品免费| 国产91综合一区在线观看| 国产精品白丝jk黑袜喷水| 成人免费视频播放| www久久精品| 久久国产精品99久久久久久老狼| 欧美在线观看18| 国产精品久久久久久久第一福利| 国产在线精品一区二区不卡了| 555www色欧美视频| 一区二区久久久久| 成人免费不卡视频| 国产亚洲欧美色| 国产一区福利在线| 欧美伦理电影网| 日韩一区二区高清| 日日摸夜夜添夜夜添国产精品| 欧洲一区二区三区在线| 一区二区三区波多野结衣在线观看| 成人少妇影院yyyy| 亚洲精品视频在线观看网站| 99riav一区二区三区| 国产精品电影院| 成人在线视频首页| 亚洲日本丝袜连裤袜办公室| 色视频一区二区| 亚洲国产美女搞黄色| 欧美视频在线一区| 亚洲成在线观看| 日韩一区二区三区免费看| 久久成人精品无人区| 久久亚洲欧美国产精品乐播 | 亚洲精品国产精华液| 国产白丝网站精品污在线入口| 久久综合狠狠综合| 国产精品一区二区你懂的| 国产精品免费av| 国产99精品视频| 久久久久国产成人精品亚洲午夜| 丁香激情综合国产| 国产偷国产偷精品高清尤物| 蜜桃传媒麻豆第一区在线观看| 精品剧情在线观看| 成人av片在线观看| 中文欧美字幕免费| 日韩激情在线观看| 国产精品人人做人人爽人人添| 91久久精品一区二区三| 日韩电影在线观看电影| 精品少妇一区二区三区日产乱码| 国产99久久久精品| 一区二区三区免费| 久久综合九色综合97婷婷女人| 成人天堂资源www在线| 亚洲曰韩产成在线| 欧美日韩一区小说| 日韩av一区二区在线影视| 精品99一区二区| 91蝌蚪porny九色| 精品一区二区免费| 亚洲综合一二三区| 久久久青草青青国产亚洲免观| 91在线观看地址| 久久电影网电视剧免费观看| 一区二区高清视频在线观看| 国产视频在线观看一区二区三区| 丁香五精品蜜臀久久久久99网站| 久久精品无码一区二区三区| 欧美高清精品3d| proumb性欧美在线观看| 精品制服美女久久| 夜夜嗨av一区二区三区| 久久久99精品久久| 日韩一区二区三区免费看 | 91精彩视频在线| 国产成人精品综合在线观看| ...av二区三区久久精品| 亚洲美女视频在线观看| 日韩欧美在线123| 成人av片在线观看| 日日欢夜夜爽一区| 国产网红主播福利一区二区| 欧美午夜精品久久久| 成人综合在线观看| 亚洲国产综合在线| 亚洲免费观看高清完整版在线观看 | 国产亚洲短视频| www.亚洲精品| 日韩**一区毛片| 久久91精品久久久久久秒播| 日韩成人伦理电影在线观看| 亚洲在线观看免费视频| 国产亚洲精品福利| 欧美本精品男人aⅴ天堂| 91免费观看国产| 丁香婷婷深情五月亚洲| 亚洲va欧美va天堂v国产综合| 亚洲欧洲在线观看av| 久久久九九九九| 26uuu另类欧美亚洲曰本| 欧美videos中文字幕| 久久日一线二线三线suv| 精品久久久久久久久久久院品网| 精品国精品国产| 国产亚洲va综合人人澡精品 | 久久精品国产网站| 狠狠色丁香久久婷婷综合_中| 经典一区二区三区| 成人夜色视频网站在线观看| k8久久久一区二区三区| 成人sese在线| 欧美亚一区二区| 7777精品伊人久久久大香线蕉完整版| 91浏览器在线视频| www.在线成人| 色狠狠色狠狠综合| 3d动漫精品啪啪1区2区免费| 日韩一区二区电影在线| 欧美国产精品久久| 国产精品你懂的| 亚洲一区欧美一区| 99久久综合狠狠综合久久| 日韩欧美激情一区| 成人一级黄色片| 亚洲成人av中文| 艳妇臀荡乳欲伦亚洲一区| 亚洲激情欧美激情| 日韩精品高清不卡| 色中色一区二区| 欧美成人猛片aaaaaaa| 91麻豆精品国产| 亚洲电影欧美电影有声小说| 国产精品99久久久久久久女警 | 欧美日韩高清一区二区不卡 | 成人av电影在线网| 欧美电视剧免费全集观看| 亚洲一二三四区| 国产乱子伦一区二区三区国色天香| 免费成人av在线播放| 99re这里都是精品| 欧美成人乱码一区二区三区| 亚洲一区二区三区中文字幕在线| 国产精品一区一区三区| 欧美一区二区三区视频在线观看| 亚洲视频精选在线| 国产成人综合视频| 日韩精品在线看片z| 亚洲成国产人片在线观看| 91免费国产在线观看| 国产精品乱子久久久久| 天天影视网天天综合色在线播放| 91在线porny国产在线看| 国产视频视频一区| 狠狠色2019综合网| 日韩女同互慰一区二区| 麻豆国产欧美一区二区三区| 日韩亚洲欧美一区二区三区| 狠狠网亚洲精品| 综合久久国产九一剧情麻豆| 亚洲视频一区二区在线观看| 日本精品一级二级| 精品一区二区三区免费毛片爱| 中文在线一区二区| 色系网站成人免费| 久久精品国产一区二区三| 久久九九影视网| 91免费国产在线| www.亚洲在线| 国产在线视频一区二区| 亚洲人成在线观看一区二区| 欧美日韩一区国产| 国产大陆a不卡| 日韩国产精品久久久| 国产精品第一页第二页第三页| 欧美日韩中文一区| 国产成人在线免费观看| 亚洲成在线观看| 欧美韩日一区二区三区| 91精品一区二区三区久久久久久 | 欧美一级黄色录像| 激情丁香综合五月| 亚洲影视资源网| 久久久精品影视| 7878成人国产在线观看| 成人少妇影院yyyy| 激情五月激情综合网| 日韩成人一区二区| 亚洲一区二区精品3399| 亚洲蜜臀av乱码久久精品|