Emit의 동적 유형 TypeBuilder에서 클래스 태그 생성에 대한 생각

9947 단어 builder

TypeBuilder를 이용하면 하나의 유형을 동적으로 만들 수 있습니다. 현재 하나의 수요가 있습니다. 동적으로 dll을 생성하고 유형EmployeeEx를 만듭니다. 원래 dll에 있는 Employee 클래스를 계승하고 Employee 클래스의 모든 클래스 표시를 포함해야 합니다.
 
인터넷에는 많은 예가 있는데,
//  TypeBuilder。   

            TypeBuilder myTypeBuilder = myModBuilder.DefineType(typeName, 

                                                            TypeAttributes.Public);



            myTypeBuilder.SetParent(type);

 
대략적인 처리 방법은 다음과 같다.
CustomAttributeBuilder customAttributeBuilder = new CustomAttributeBuilder(typeof(SerializableAttribute).GetConstructor(Type.EmptyTypes), new Type[] { }); 

      myTypeBuilder.SetCustomAttribute(customAttributeBuilder);







att = type.GetCustomAttributes(typeof(DefaultPropertyAttribute), false); 

            if (att != null && att.Length > 0) { 

                DefaultPropertyAttribute dea = att[0] as DefaultPropertyAttribute; 

                customAttributeBuilder = new CustomAttributeBuilder(typeof(DefaultPropertyAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { dea.Name }); 

                myTypeBuilder.SetCustomAttribute(customAttributeBuilder); 

             }

 
그러나 이것은 이미 알고 있는 클래스 표시가 Serializable 또는Default Property입니다. 만약에 원래 dll에 있는 Employee에 사용자 정의 표시를 추가하면, 클래스 표시, Type Builder를 어떻게 동적으로 계승할 수 있는지 프로그램을 바꿔야 합니다.SetCustom Attribute는 SetCustom Attribute(Custom Attribute Builder custom Builder)와 SetCustom Attribute(Constructor Info con,byte[] binary Attribute) 2개를 리셋합니다.둘 다 클래스 태그를 구성하려면 ConstructorInfo가 필요합니다.우리가 유형 Employee를 통해 얻은 클래스 표시는 반사된 Object[] atts = type입니다.GetCustomAttributes(false);이것은 Object 배열이므로 ConstructorInfo에 직접 사용할 수 없습니다.
 
그래서 아래의 코드가 생겨서 동적으로 표시가 생겼다.
#region   

            object[] atts = type.GetCustomAttributes(false);

            if (atts != null && atts.Length > 0) {

                foreach (Attribute item in atts) {

                    if (item == null) continue;

                    try {

                        CustomAttributeBuilder c = null;

                        ConstructorInfo[] conInfos = item.GetType().GetConstructors();

                        ConstructorInfo cons = conInfos[conInfos.Length - 1];

                        ParameterInfo[] args = cons.GetParameters();

                        List<Type> argsList = new List<Type>();

                        List<object> argsValue = new List<object>();

                        if (args.Length > 0) {

                            foreach (var arg in args) {

                                argsList.Add(arg.ParameterType);

                                PropertyInfo pi = item.GetType().GetProperty(arg.Name.Substring(0, 1).ToUpper() + arg.Name.Substring(1));//         

                                if (pi != null) {

                                    argsValue.Add(pi.GetValue(item, null));

                                } else {

                                    pi = item.GetType().GetProperty(arg.Name.Remove(0, 1));//     p+Name

                                    if (pi != null) {

                                        argsValue.Add(pi.GetValue(item, null));

                                    } else {

                                        argsValue.Add(null);

                                    }

                                }

                            }

                        }

                        PropertyInfo[] pis = item.GetType().GetProperties();

                        if (pis.Length > 0) {

                            List<PropertyInfo> piList = new List<PropertyInfo>();

                            List<object> valueList = new List<object>();

                            object[] pValues = new object[pis.Length];

                            for (int i = 0; i < pis.Length; i++) {

                                if (pis[i].CanWrite) {

                                    pValues[i] = pis[i].GetValue(item, null);

                                    if (pValues[i] != null) {

                                        piList.Add(pis[i]);

                                        valueList.Add(pValues[i]);

                                    }

                                }

                            }

                            if (piList.Count > 0) {

                                c = new CustomAttributeBuilder(cons, argsValue.ToArray(), piList.ToArray(), valueList.ToArray());

                            } else {

                                c = new CustomAttributeBuilder(cons, argsValue.ToArray());

                            }

                        } else {

                            c = new CustomAttributeBuilder(cons, argsValue.ToArray());

                        }

                        myTypeBuilder.SetCustomAttribute(c);

                    } catch (Exception ex) {

                        throw new Exception(string.Format("{0}   [{1}]    :{2}", typeName, item.ToString(),ex.ToString()));

                    }

                }

            }

좋은 웹페이지 즐겨찾기