コード例 #1
0
        /// <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);
            }
        }
コード例 #2
0
        /// <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);
        }
コード例 #3
0
        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);
        }