網頁

2011年9月23日 星期五

dotNet Dynamic Compile Code

Last Update: 2011/09/23 16:51+08

Intro

動態編譯程式碼!!
並不是動態產生程式碼!!
目的請各位看倌自行應用
小弟是讓使用者可以自己輸入折扣/特價

底下會分幾段
1. Dynamic Compile Code
  a. Compiler Parameters
  b. Code
  c. Compile
  d. Run
2. Sample Code


Content


1. Dynamic Compile Code
底下為動態 Compile Code 並執行的方法
一開始要創建 Code Provider, 用來Compile
static object RunCode(string code){
    var provider = Microsoft.CSharp.CSharpCodeProvider.CreateProvider("C#");

    /*---Compiler Parameters---*/
    var compilerParams = new System.CodeDom.Compiler.CompilerParameters();
    compilerParams.ReferencedAssemblies.Add("System.dll");
    compilerParams.GenerateExecutable = false;
    compilerParams.GenerateInMemory = false;


    /*---Code---*/
    System.Text.StringBuilder fileCode = new StringBuilder();
    fileCode.Append("using System; \n")
        .Append("public class TestDynCode{")
            .Append("public object Run(){")
                .Append(code)
            .Append("}")
        .Append("}");


    /*---Compile---*/
    var compilerResult = provider.CompileAssemblyFromSource(compilerParams, fileCode.ToString());
    if (compilerResult.Errors.HasErrors){
        System.Text.StringBuilder error = new StringBuilder();
        foreach (System.CodeDom.Compiler.CompilerError err in compilerResult.Errors)
        { error.AppendFormat("{0}\n", err.ErrorText); }
        throw new Exception("Error Compiling Expression: " + error.ToString());
    }

    /*---Run---*/
    System.Reflection.Assembly assembly = compilerResult.CompiledAssembly;
    var obj = assembly.CreateInstance("TestDynCode");
    return obj.GetType().GetMethod("Run").Invoke(obj, null);
}

大致可以分為 4 段
跟我們平常開發的方式差不多

a. Compiler Parameters
先設置參數, 包含要加入參考的 Lib
和 Compile 環境等等參數

b. Code
開始寫Code, 內容跟平常寫Code一樣, 只是變成字串
這邊為了方便, 已經寫好 class 和 method 名稱
使用時, 只要傳來裡面的 Code

c. Compile
Compile (Build)
寫好Code當然就直接Compile看看能不能過了
可以從 compilerResult 這物件去取得 Compile Error

d. Run
取得它Compile好的Assembly
創建物件實體, 最後 Invoke Method

動態編譯Code大概就醬


2. Sample Code
這裡稍微寫一小段測試的Code
GetTotalPrice: 給價格 和 數量 算總價, 裡頭暫時寫死了計算規則
Main: 呼叫 GetTotalPrice 列出結果
static void Main(string[] args){
    Console.WriteLine(GetTotalPrice(10, 9));
    Console.WriteLine(GetTotalPrice(10, 4));
    Console.ReadKey();
}

static object GetTotalPrice(decimal price, int count){
    string inputRule = "return [數量] > 5 ? [價格] * [數量] * 0.9 : [價格] * [數量];";//賣方Input

 //實際要Run的Code
    string realInputRule = inputRule
        .Replace("[數量]", count.ToString())
        .Replace("[價格]", price.ToString());
    return RunCode(realInputRule);
}

感謝各位看倌賞臉~

沒有留言:

張貼留言