Dynamically create classes and dynamically create

Source: Internet
Author: User
Tags list of attributes

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.

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.