反射是動態獲取程序集的元數據的一種技術,這句話是作.NET程序員面試題目的一個的答案,你可選擇記住它,就比如高中生物學裏面講到的細胞的結構的課程時,細胞由細胞膜,細胞質和細胞核組成。根據作程序的經驗,Never ask why不是好習慣,即便是微軟的API,有時候違反了調用約定,也會很抓狂。
請看下面這一段代碼
Assembly assembly = Assembly.GetExecutingAssembly();程序員
object entryForm = Activator.CreateInstance(formBaseType) as Form;面試
entryForm .MdiParent = this;
entryForm .Show();
entryForm .Activate();
代碼的含義比較簡單,從當前程序集中建立formBaseType類型,並調用它的方法。從方法名上來看,大概能夠看出,這是一段MDI建立child子窗體,並顯示子窗體的代碼。
這段小代碼,也是插件式框架的基本思路,請參考《Management Console 工具管理類軟件通用開發框架(開放源碼)》中的例子來體會它的用處。
在ERP/MIS系統中,應用反射的例子,實在是太多了。數據訪問接口InventoryMovementDAL,藉助於反射,來查找並調用它的實現類; 窗體也它的子窗體藉助於反射來獲取屬性,傳遞值;ERP系統的整個框架,也是藉助於反射搭建起來.
看下面的圖,ERP的三個模塊Paradox.ERP.SystemAdministration, Paradox.ERP.Engineering,Paradox.ERP.Inventory被Paradox.Framework.Kernal反射調用,若是再寫一個Paradox.ERP.Sales的銷售模塊,幾乎不須要改動,就能夠讓它被框架調用。框架
對於如何解析工資的formular公式,有若干種辦法,這裏使有的是動態編譯的方法。把每個工資項當作是一個類型class的屬性,Formular的內容則放到一個方法中去,當成表達式計算求職,最後應用反射,返回各屬性的值便可。
public class FormularCalculation
{
public static object Build(string[] items, string formular)
{
string nameSpace = "A";
string className = "FormularCalculation";
string methodName = "Run";
CSharpCodeProvider compiler = new CSharpCodeProvider();
CompilerParameters paras = new CompilerParameters();
paras.GenerateExecutable = false;
paras.GenerateInMemory = true;
StringBuilder classSrc = new StringBuilder();
classSrc.Append(" using System;"+Environment.NewLine);
classSrc.Append(" namespace "+nameSpace+" { " + Environment.NewLine);
classSrc.Append("public class " + className + "{ " + Environment.NewLine);
foreach (string item in items)
{
classSrc.Append("public decimal " + item + ";" + Environment.NewLine);
}
classSrc.Append("public void Run() { 基本工資=5000; " + Environment.NewLine);
string [] format= Regex.Split(formular,Environment.NewLine);
foreach (string prop in format)
{
classSrc.Append(prop +" ;"+ Environment.NewLine);
}
classSrc.Append("}"+Environment.NewLine);
classSrc.Append("}" + Environment.NewLine);
classSrc.Append("}" + Environment.NewLine);
string source = classSrc.ToString();
CompilerResults result = compiler.CompileAssemblyFromSource(paras, source);
CompilerErrorCollection error= result.Errors;
Assembly assembly = result.CompiledAssembly;
object eval = assembly.CreateInstance(nameSpace+"."+className);
MethodInfo method = eval.GetType().GetMethod(methodName);
object reobj = method.Invoke(eval, null);
return eval;
}
}
調用方法以下
string[] items = { "應發合計","基本工資","獎金","福利費", "扣款合計","社保","稅","實發合計","應稅所得額"};
string formular=@ 」 應發合計=基本工資+ 獎金 + 福利費 - 扣款合計;
扣款合計=社保 + 稅+ 應稅所得額;
實發合計=應發合計- 扣款合計; ";
object obj = FormularCalculation.Build(items, formular);
Type type = obj.GetType();
foreach (PropertyInfo fi in type.GetProperties(BindingFlags.NonPublic | BindingFlags.Public
| BindingFlags.Instance | BindingFlags.DeclaredOnly))
{
string value = fi.Name; //取到計算後的各個屬性的值
}
動態編譯還應用於軟件的加密,在內存中產生加密程序的源代碼,動態編譯並運行,檢測是否符合license受權。 工具