代碼的動態編譯並執行是一個NET平台提供給我們的很強大的工具用以靈活擴展(當然是面對內部開發人員)復雜而無法估算的邏輯並通過一些額外的代碼來擴展我們已有 的應用程序這在很大程度上給我們提供了另外一種擴展的方式(當然這並不能算是嚴格意義上的擴展但至少為我們提供了一種思路)
動態代碼執行可以應用在諸如模板生成外加邏輯擴展等一些場合一個簡單的例子為了網站那的響應速度HTML靜態頁面往往是我們最好的選擇但基於數據驅動的網站往往又很難用靜態頁面實現那麼將動態頁面生成html的工作或許就是一個很好的應用場合另外對於一些模板的套用我們同樣可以用它來做另外這本身也是插件編寫的方式
最基本的動態編譯
Net為我們提供了很強大的支持來實現這一切我們可以去做的基礎主要應用的兩個命名空間是SystemCodeDomCompiler和MicrosoftCSharp或MicrosoftVisualBasic另外還需要用到反射來動態執行你的代碼動態編譯並執行代碼的原理其實在於將提供的源代碼交予CSharpCodeProvider來執行編譯(其實和CSC沒什麼兩樣)如果沒有任何編譯錯誤生成的IL代碼會被編譯成DLL存放於於內存並加載在某個應用程序域(默認為當前)內並通過反射的方式來調用其某個方法或者觸發某個事件等之所以說它是插件編寫的一種方式也正是因為與此我們可以通過預先定義好的借口來組織和擴展我們的程序並將其交還給主程序去觸發一個基本的動態編譯並執行代碼的步驟包括
· 將要被編譯和執行的代碼讀入並以字符串方式保存
· 聲明CSharpCodeProvider對象實例
· 調用CSharpCodeProvider實例的CompileAssemblyFromSource方法編譯
· 用反射生成被生成對象的實例(AssemblyCreateInstance)
· 調用其方法
以下代碼片段包含了完整的編譯和執行過程
//get the code to compile
string strSourceCode = this
txtSource
Text;
//
Create a new CSharpCodePrivoder instance
CSharpCodeProvider objCSharpCodePrivoder = new CSharpCodeProvider();
//
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;
//
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 =
; 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;
}
//
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[
];
objCodeParms[
] =
Allan
;
string strResult = (string)objClass
GetType()
InvokeMember(
GetTime
BindingFlags
InvokeMethod
null
objClass
objCodeParms);
this
txtResult
Text = strResult;
[] [] [] [] []
From:http://tw.wingwit.com/Article/program/net/201311/14508.html