/// <summary> /// Adds the custom attribute. /// </summary> /// <param name="propertyBuilder">The property builder.</param> /// <param name="attr">The attribute information.</param> private void AddCustomAttribute(PropertyBuilder propertyBuilder, PropertyAttributeInformation attr) { Type caType = attr.AttributeType; Type[] types = new Type[attr.AttributeValues.Count]; var attrValues = attr.AttributeValues.Select(x => x.Value).ToArray(); int i = 0; ConstructorInfo con; PropertyInfo[] attrPropertyInfos = new PropertyInfo[attr.AttributeValues.Count]; foreach (var attrProp in attr.AttributeValues) { if (attr.AttributeType != null) { attrPropertyInfos[i] = attr.AttributeType.GetProperty(attrProp.Key); } if (attrProp.Value != null) { types[i] = attrProp.Value.GetType(); } else { types[i] = attrPropertyInfos[i].PropertyType; } i++; } if (caType == null) { //return; con = CreateOwnAttributeConstructor(attr); CustomAttributeBuilder stiAttrib = new CustomAttributeBuilder(con, attrValues); propertyBuilder.SetCustomAttribute(stiAttrib); } else { CustomAttributeBuilder stiAttrib; con = caType.GetConstructor(types); if (con == null) { con = caType.GetConstructor(new Type[0]); stiAttrib = new CustomAttributeBuilder(con, new object[0]); } else { stiAttrib = new CustomAttributeBuilder(con, attrValues); } propertyBuilder.SetCustomAttribute(stiAttrib); } }
/// <summary> /// Gets the custom attributes. /// </summary> /// <param name="property">The property.</param> /// <returns></returns> private static List <PropertyAttributeInformation> GetCustomAttributes(this PropertyInfo property) { var customAttributes = new List <PropertyAttributeInformation>(); var attrs = property.GetCustomAttributes(true); foreach (var atr in attrs) { var caProperties = atr.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); var caValues = caProperties.Where(nValue => nValue.Name != "TypeId").ToDictionary(nValue => nValue.Name, nValue => nValue.GetValue(atr, null)); var attribInfo = new PropertyAttributeInformation { AttributeType = atr.GetType(), AttributeValues = caValues }; customAttributes.Add(attribInfo); } return(customAttributes); }
private ConstructorInfo CreateOwnAttributeConstructor(PropertyAttributeInformation attr) { //return null; var typeSignature = attr.Name; //var an = new AssemblyName(typeSignature + ",Version=1.0.0.1"); ////генерация динамической сборки только с возможностью запуска //AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, // AssemblyBuilderAccess.RunAndSave); //ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(typeSignature + ".MainModule", typeSignature + ".dll", true); var moduleTypes = mModuleBuilder.GetTypes().ToList(); //todo проверить список типо на наличие уже сгенерированного //todo и вообще сделать это на уровень выше и если тип уже есть то идти по стандартному пути получения конструктора //todo а ещё лучше тут не конструктор получать а генерировать и задавать тип для PropertyAttributeInformation if (moduleTypes.FirstOrDefault(x => x.Name == typeSignature) == null) { } TypeBuilder tb = mModuleBuilder.DefineType(typeSignature, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout, null); tb.SetParent(typeof(Attribute)); tb.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName); foreach (var val in attr.AttributeValues) { var field = new PropertyInformation { PropertyName = val.Key, PropertyValue = val.Value, PropertyType = val.Value.GetType() }; CreateProperty(field, tb); } Type[] types = new Type[attr.AttributeValues.Count]; int i = 0; foreach (var attrProp in attr.AttributeValues) { types[i] = attrProp.Value.GetType(); i++; } var constructor = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, types); ILGenerator myConstructorIL = constructor.GetILGenerator(); myConstructorIL.Emit(OpCodes.Ldarg_0); myConstructorIL.Emit(OpCodes.Ldarg_1); myConstructorIL.Emit(OpCodes.Stfld, attr.AttributeValues.FirstOrDefault().Key); myConstructorIL.Emit(OpCodes.Ret); return(constructor as ConstructorInfo); }