有時候在整個項目架構裡也需要動態建立程式集的需求,那如何建立程式集呢,請跟我來學習一下吧。
首先需要知道動態建立這些類型是使用的一些什麼技術呢?其實只要相關動態載入程式集呀,類呀,都是使用反射,那麼動態建立也一樣使用的是反射,是屬於反射的技術!也就是將對象或者資料對應成一個對象或者程式集儲存起來而已。
首先我們需要瞭解每個動態類型在.net中都是用什麼類型來表示的。
程式集:System.Reflection.Emit.AssemblyBuilder(定義並表示動態程式集)
建構函式:System.Reflection.Emit.ConstructorBuilder(定義並表示動態類的建構函式)
自訂屬性:System.Reflection.Emit.CustomAttributeBuilder(協助產生自訂屬性 使用建構函式傳遞的參數來產生類的屬性)
枚舉:System.Reflection.Emit.EnumBuilder(說明並表示枚舉類型)
事件:System.Reflection.Emit.EventBuilder(定義類的事件)
欄位:System.Reflection.Emit.FieldBuilder(定義並表示欄位。無法繼承此類)
局部變數:System.Reflection.Emit.LocalBuilder(表示方法或建構函式內的局部變數)
方法:System.Reflection.Emit.MethodBuilder(定義並表示動態類的方法(或建構函式))
模組:System.Reflection.Emit.ModuleBuilder(定義和表示動態程式集中的模組)
參數:System.Reflection.Emit.ParameterBuilder(建立或關聯參數資訊 如:方法參數,事件參數等)
屬性:System.Reflection.Emit.PropertyBuilder(定義類型的屬性 (Property))
類:System.Reflection.Emit.TypeBuilder(在運行時定義並建立類的新執行個體)
我們有了這些類型,基本上就可以動態建立我們的任何需要使用的類型,當然很多可以動態建立的類型我不可能都介紹完,如果在項目中有需要可以去查閱MSDN,裡面都有DEMO的,主要的問題就是要理解每一種類型的定義,比如:程式集載入是靠AppDomain,程式集裡包含多個模組,模組裡可以聲明類,類裡可以建立方法、屬性、欄位。方法需要在類中才可以建立的,局部變數是聲明在方法體內等等規則。看MSDN就非常容易弄懂了。
1.如何動態建立它們了
AppDomain:應用程式定義域(由 AppDomain 對象表示)為執行Managed 程式碼提供隔離、卸載和安全邊界。AppDomain同時可以載入多個程式集,共同來實現功能。
程式集:簡單來說就是一個以公用語言運行庫(CLR)為宿主的、版本化的、自描述的二進位檔案。(說明:定義來自C#與.NET3.5進階程式設計(第四版))
模組:類似於以前的單元,用於分割不同的類和類型,以及資源(resource, 資源記錄就是字串,圖象以及其它資料,他們只在需要的時候才會被調入記憶體)。類型的Meta資訊也是模組的一部分。多個模組組建成一個程式集。
所謂動態就是在程式運行時,動態建立和使用。
直接看代碼吧,其實超級簡單。
//動態建立程式集
AssemblyName DemoName = new AssemblyName("DynamicAssembly");
AssemblyBuilder dynamicAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(DemoName, AssemblyBuilderAccess.RunAndSave);
//動態建立模組
ModuleBuilder mb = dynamicAssembly.DefineDynamicModule(DemoName.Name, DemoName.Name + ".dll");
//動態建立類MyClass
TypeBuilder tb = mb.DefineType("MyClass", TypeAttributes.Public);
//動態建立欄位
FieldBuilder fb = tb.DefineField("", typeof(System.String), FieldAttributes.Private);
//動態建立建構函式
Type[] clorType = new Type[] { typeof(System.String) };
ConstructorBuilder cb1 = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, clorType);
//產生指令
ILGenerator ilg = cb1.GetILGenerator();//產生 Microsoft 中繼語言 (MSIL) 指令
ilg.Emit(OpCodes.Ldarg_0);
ilg.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes));
ilg.Emit(OpCodes.Ldarg_0);
ilg.Emit(OpCodes.Ldarg_1);
ilg.Emit(OpCodes.Stfld, fb);
ilg.Emit(OpCodes.Ret);
//動態建立屬性
PropertyBuilder pb = tb.DefineProperty("MyProperty", PropertyAttributes.HasDefault, typeof(string), null);
//動態建立方法
MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName;
MethodBuilder myMethod = tb.DefineMethod("get_Property", getSetAttr, typeof(string), Type.EmptyTypes);
//產生指令
ILGenerator numberGetIL = myMethod.GetILGenerator();
numberGetIL.Emit(OpCodes.Ldarg_0);
numberGetIL.Emit(OpCodes.Ldfld, fb);
numberGetIL.Emit(OpCodes.Ret);
//儲存動態建立的程式集
dynamicAssembly.Save(DemoName.Name + ".dll");
第二篇:C# 動態建立和動態使用程式集、類、方法、欄位等(二)