Dynamically create classes and dynamically create
First, I would like to share with you a few links:
Http://www.cnblogs.com/longgel/archive/2010/05/14/1735590.html
Http://www.cnblogs.com/yjmyzz/archive/2011/11/13/2247600.html
Http://www.cnblogs.com/lichdr/archive/2004/10/21/55038.html
In fact, the content is not much different, just for record.
//--------------------------------------------------------
// Author: Li Jian msn: newshadowk@hotmail.com, this is the source code author, I just copy to change
//--------------------------------------------------------
/// <Summary>
/// Class helper, which can dynamically control (add or delete) Class and Class Members. Currently, only attribute control is supported.
/// Note that other members except the attribute will be cleared and the function will be improved so that it will not affect other members.
/// </Summary>
Public class DynamicClass {// public method # region public method // <summary> // create a class instance based on the type of the class. /// </Summary> /// <param name = "t"> type to be created. </Param> // <returns> returns the created class instance. </Returns> public static object CreateInstance (Type t) {return Activator. createInstance (t) ;}/// <summary> /// create a type instance based on the class name and attribute list. /// </Summary> /// <param name = "className"> name of the class to be created. </Param> /// <param name = "lcpi"> list of attributes of the class to be created. </Param> // <returns> return the created class instance </returns> public static object CreateInstance (string className, List <CustPropertyInfo> lcpi) {Type t = SetObjectAndAddPropertyToType (className, lcpi); return Activator. createInstance (t);} // <summary> // create an instance of the Class Based on the attribute list. The default class name is DefaultClass. Because the generated class is not of a strong type, therefore, the class name can be ignored. /// </Summary> /// <param name = "lcpi"> list of attributes of the class to be created </param> /// <returns> instance. </Returns> public static object CreateInstance (List <CustPropertyInfo> lcpi) {return CreateInstance ("DefaultClass", lcpi );} /// <summary> /// set the class attributes based on the instance of the class. /// </Summary> /// <param name = "classInstance"> instance of the class to be set. </Param> /// <param name = "propertyName"> the property name to be set. </Param> /// <param name = "propertSetValue"> the property value to be set. </Param> public static void SetPropertyValue (object classInstance, string propertyName, object propertSetValue) {classInstance. getType (). invokeMember (propertyName, BindingFlags. setProperty, null, classInstance, new object [] {Convert. changeType (propertSetValue, propertSetValue. getType ()});} public static void SetPropertyValue (object classInstance, ProPertyVale valueInfo) {var properties = clas SInstance. getType (). getProperties (); if (properties. where (p => p. name = valueInfo. name ). count () <= 0) return; var item = properties. single (p => p. name = valueInfo. name); item. setValue (classInstance, StrToLevelEnum (valueInfo. value);} public static St. domain. entity. levelInfo StrToLevelEnum (string value) {int val = Convert. toInt32 (value); return (Domain. entity. levelInfo) val ;}/// <summary> /// Obtains the attributes of a Class Based on the instance of the class. /// </Summary> /// <param name = "classInstance"> instance of the class to be obtained </param> /// <param name = "propertyName"> the property name. </Param> /// <returns> returns the attributes of the obtained class. </Returns> public static object GetPropertyValue (object classInstance, string propertyName) {return classInstance. getType (). invokeMember (propertyName, BindingFlags. getProperty, null, classInstance, new object [] {});} # endregion // Private method # region private method /// <summary> /// merge attributes in the instance t and lcpi parameters. /// </Summary> /// <param name = "t"> instance t </param> /// <param name = "lcpi"> that contains the attribute list information. </Param> private static void MergeProperty (Type t, List <CustPropertyInfo> lcpi) {CustPropertyInfo cpi; foreach (PropertyInfo pi in t. getProperties () {cpi = new CustPropertyInfo (pi. propertyType, pi. name, pi. attributes. toString (); lcpi. add (cpi) ;}//< summary> /// remove the property list lcpi from the properties of instance t. The returned new property list is in lcpi. /// </Summary> /// <param name = "t"> type instance t. </Param> /// <param name = "lcpi"> list of attributes to be removed. </Param> private static List <CustPropertyInfo> SeparateProperty (Type t, List <string> ls) {List <CustPropertyInfo> ret = new List <CustPropertyInfo> (); CustPropertyInfo cpi; foreach (PropertyInfo pi in t. getProperties () {foreach (string s in ls) {if (pi. name! = S) {cpi = new CustPropertyInfo (pi. propertyType, pi. name); ret. add (cpi) ;}}return ret ;}/// <summary> /// Add the attributes in the lcpi parameter to myTypeBuilder. Note: This operation will remove other members and its functions need to be improved. /// </Summary> /// <param name = "myTypeBuilder"> Type constructor instance. </Param> /// <param name = "lcpi"> contains information about the attribute list. </Param> private static void construct (TypeBuilder myTypeBuilder, List <CustPropertyInfo> lcpi) {consumer metadata; PropertyBuilder attributes; Consumer metadata; MethodBuilder attributes; MethodAttributes getSetAttr; ILGenerator attributes; // attribute Set and Get must have a special attribute. Set this parameter to Public. GetSetAttr = MethodAttributes. Public | MethodAttributes. SpecialName | MethodAttributes. HideBySig; // Add attributes to myTypeBuilder. Foreach (CustPropertyInfo cpi in lcpi) {// defines the field. CustomerNameBldr = myTypeBuilder. defineField (cpi. fieldName, cpi. type, FieldAttributes. private); // get ConstructorInfo classCtorInfo = typeof (DisplayNameAttribute ). getConstructor (new Type [] {typeof (string)}); // dynamically create ClassCreatorAttribute CustomAttributeBuilder tyAttribute = new CustomAttributeBuilder (classCtorInfo, new object [] {cpi. attributeName}); // defines attributes. // The last parameter is null because there is no parameter in the property. CustNamePropBldr = myTypeBuilder. DefineProperty (cpi. PropertyName, PropertyAttributes. HasDefault, cpi. Type, null); custNamePropBldr. SetCustomAttribute (tyAttribute); // Add the [DisplayName ("")] feature. // Var tyS = custNamePropBldr. CustomAttributes; // define the Get method. CustNameGetPropMthdBldr = myTypeBuilder. defineMethod (cpi. getPropertyMethodName, getSetAttr, cpi. type, Type. emptyTypes); custNameGetIL = custNameGetPropMthdBldr. getILGenerator (); custNameGetIL. emit (OpCodes. ldarg_0); // you can view Emit-related information. http://www.cnblogs.com/lichdr/archive/2004/10/21/55038.html CustNameGetIL. Emit (OpCodes. lddes, customerNameBldr); custNameGetIL. Emit (OpCodes. Ret); // defines the Set method. CustNameSetPropMthdBldr = myTypeBuilder. defineMethod (cpi. setPropertyMethodName, getSetAttr, null, new Type [] {cpi. type}); custNameSetIL = custNameSetPropMthdBldr. getILGenerator (); custNameSetIL. emit (OpCodes. ldarg_0); custNameSetIL. emit (OpCodes. ldarg_1); custNameSetIL. emit (OpCodes. stfld, customerNameBldr); custNameSetIL. emit (OpCodes. ret); // Add the two methods (Get, Set) created to PropertyBuilder. CustNamePropBldr. SetGetMethod (custNameGetPropMthdBldr); custNamePropBldr. SetSetMethod (custNameSetPropMthdBldr); }}/// <summary> /// add attributes to a type instance. /// </Summary> /// <param name = "classType"> type instance. </Param> /// <param name = "lcpi"> list of attributes to be added. </Param> // <returns> returns the processed instance type. </Returns> public static Type SetObjectAndAddPropertyToType (string name, List <CustPropertyInfo> lcpi) {AppDomain myDomain = Thread. getDomain (); AssemblyName myAsmName = new AssemblyName (); myAsmName. name = "DynamicAssembly"; // create a Permanent Assembly and set it to AssemblyBuilderAccess. runAndSave. AssemblyBuilder myAsmBuilder = myDomain. DefineDynamicAssembly (myAsmName, AssemblyBuilderAccess. RunAndSave); // create a permanent single-mode program block. ModuleBuilder myModBuilder = myAsmBuilder. DefineDynamicModule (myAsmName. Name, myAsmName. Name + ". dll"); // create a TypeBuilder. TypeBuilder myTypeBuilder = myModBuilder. DefineType (name, TypeAttributes. Public); // Add the attributes defined in lcpi to TypeBuilder. Other members are cleared. Its functions need to be extended so that it does not affect other members. AddPropertyToTypeBuilder (myTypeBuilder, lcpi); // creation type. Type retval = myTypeBuilder. CreateType (); // The Persistence set, which can be parsed by ildasm.exe or referenced by the test program. MyAsmBuilder. save (myAsmName. name + ". dll "); return retval ;}# endregion // helper class # region helper class /// <summary> /// custom attribute information type. /// </Summary> public class CustPropertyInfo {private string propertyName; private Type type; private string attributeName; // <summary> // empty structure. /// </Summary> public CustPropertyInfo () {}/// <summary> /// construct an instance based on the attribute type name and attribute name. /// </Summary> /// <param name = "type"> attribute type name. </Param> /// <param name = "propertyName"> attribute name. </Param> public CustPropertyInfo (Type type, string propertyName) {this. type = type; this. propertyName = propertyName;} // <summary> // construct an instance based on the attribute type name and attribute name. /// </Summary> /// <param name = "type"> attribute type name. </Param> /// <param name = "propertyName"> attribute name. </Param> // <param name = "attributeName"> description feature value </param> public CustPropertyInfo (Type type, string propertyName, string attributeName) {this. type = type; this. propertyName = propertyName; this. attributeName = attributeName;} // <summary> // obtain or set the attribute type name. /// </Summary> public Type {get {return type;} set {type = value ;}/// <summary> /// get or set the attribute name. /// </Summary> public string PropertyName {get {return propertyName;} set {propertyName = value ;}} /// <summary> /// obtain or set the feature name /// </summary> public string AttributeName {get {return attributeName;} set {attributeName = value ;}} /// <summary> /// obtain the attribute field name. /// </Summary> public string FieldName {get {return $ "_ {propertyName. substring (0, 1 ). toLower ()} {propertyName. substring (1)} ";}}/// <summary> /// obtain the Set Method Name of the attribute in IL. /// </Summary> public string SetPropertyMethodName {get {return "set _" + PropertyName ;}} /// <summary> /// Get the Get Method Name of the attribute in IL. /// </Summary> public string GetPropertyMethodName {get {return "get _" + PropertyName ;}}# endregion}
This help class can be expanded to a wider extent. I hope to help you.