通過字串動態建立類物件

atliwen發表於2015-09-29

通過字串動態建立類物件

 

      功能的需求是  不需要使用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());

 

 

 

希望 哪位大神 有更高效 的 方式  可以告訴本人一下哈 。。 

 

相關文章