通過字串動態建立類物件
功能的需求是 不需要使用IOC 框架 來對建立指定物件。
.NET 中 要想動態的 建立物件 做耦合 好像只能做到 將類生成DLL 後 然後 載入DLL 接著建立物件。
JAVA 當個類檔案 就可以執行。
希望做到 當讀一個 .class 或者 .TXT 就可以 動態建立類物件 那多好啊!!! 還可以將 類檔案 以字串的形式寫到 資料庫中 通過資料庫來 建立類物件。
然後就各種百度 谷歌 貼吧等 找有沒相關的 解決方案 還好 找到了 。 不藏著 分享出來
程式碼很簡單:
CSharpCodeProvider p = new CSharpCodeProvider(); CompilerParameters param = new CompilerParameters(); string s = "public class AAA{ public string name;}"; CompilerResults rel = p.CompileAssemblyFromSource(param, s); Type t = rel.CompiledAssembly.GetType("AAA"); object o = t.GetConstructor(System.Type.EmptyTypes).Invoke(null); string sdc = t.GetField("name").GetValue(o).ToString(); Console.WriteLine(t.GetField("name").GetValue(o).ToString());
下面是 我做的詳解 和 效能時間
new AAA(); // new 一個 AAA 的時間是 0.3314 毫秒 Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); // 開始監視程式碼執行時間 // 是編譯器 類 CompilerParameters param = new CompilerParameters(); //param.OutputAssembly = "myTest.dll";// 設定生成的程式集名稱 EXE還是DLL 執行設定字尾 param.GenerateInMemory = true; // 是否寫入到記憶體中 而不是磁碟 寫入記憶體 程式集名稱設定無效 param.IncludeDebugInformation = false; //是否在已編譯的可執行檔案中包含除錯資訊。 // 設定生成的檔案地址。 false 是表示不生成詳細檔案 只生成一個DLL 或EXE //param.TempFiles = new TempFileCollection(".", false); string s = " public class AAA { public string name;}"; // 通過CSharpCodeProvider 從包含原始碼的字串的指定陣列(params string[]),使用指定的編譯器設定編譯程式集 // 也就是通過 改類 來建立一個DLL // 構造型別 提供對 C# 程式碼生成器和程式碼編譯器的例項的訪問 CompilerResults rel = null; using (CSharpCodeProvider p = new CSharpCodeProvider()) rel = p.CompileAssemblyFromSource(param, s); stopwatch.Stop(); // 停止監視 TimeSpan timespan = stopwatch.Elapsed; Console.WriteLine(timespan.TotalMilliseconds);// 170 毫秒 var sdsd = param.TempFiles;// 獲取或設定包含臨時檔案的集合 可以看生成檔案到哪裡了 // 直接獲取建立的型別 Type t = rel.CompiledAssembly.GetType("AAA"); // 獲取全部型別 Type[] tsTypes = rel.CompiledAssembly.GetTypes(); // try 一下 保證不會出現空引用 // 本地程式集中沒有 需要使用物件的 引用程式集 用反射來 賦值 呼叫方法 object o = t.GetConstructor(System.Type.EmptyTypes).Invoke(null); Stopwatch stopwatch1 = new Stopwatch(); stopwatch1.Start(); // 開始監視程式碼執行時間 t.GetField("name").SetValue(o, "1"); // 1毫秒 t.GetField("name").GetValue(o); // 1毫秒 stopwatch1.Stop(); // 停止監視 TimeSpan timespan1 = stopwatch1.Elapsed; Console.WriteLine(timespan1.TotalMilliseconds); Console.WriteLine(t.GetField("name").GetValue(o).ToString());
希望 哪位大神 有更高效 的 方式 可以告訴本人一下哈 。。