private static void AddProperty(TypeMeta.TypePropertyMeta property, TypeBuilder builder, Type baseType)
        {
            PropertyBuilder propertyBuilder = builder.DefineProperty(property.PropertyName, PropertyAttributes.None, property.PropertyType, null);

            foreach (var item in property.AttributeMetas)
            {
                if (item.ConstructorArgTypes == null)
                {
                    item.ConstructorArgTypes  = new Type[0];
                    item.ConstructorArgValues = new object[0];
                }
                ConstructorInfo        cInfo    = item.AttributeType.GetConstructor(item.ConstructorArgTypes);
                PropertyInfo[]         pInfos   = item.Properties.Select(m => item.AttributeType.GetProperty(m)).ToArray();
                CustomAttributeBuilder aBuilder = new CustomAttributeBuilder(cInfo, item.ConstructorArgValues, pInfos, item.PropertyValues);
                propertyBuilder.SetCustomAttribute(aBuilder);
            }

            MethodAttributes attributes       = MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Public;
            MethodBuilder    getMethodBuilder = builder.DefineMethod("get_" + property.PropertyName, attributes, property.PropertyType, Type.EmptyTypes);
            ILGenerator      iLGenerator      = getMethodBuilder.GetILGenerator();
            MethodInfo       getMethod        = baseType.GetMethod("GetValue").MakeGenericMethod(new Type[] { property.PropertyType });

            iLGenerator.DeclareLocal(property.PropertyType);
            iLGenerator.Emit(OpCodes.Nop);
            iLGenerator.Emit(OpCodes.Ldarg_0);
            iLGenerator.Emit(OpCodes.Ldstr, property.PropertyName);
            iLGenerator.EmitCall(OpCodes.Call, getMethod, null);
            iLGenerator.Emit(OpCodes.Stloc_0);
            iLGenerator.Emit(OpCodes.Ldloc_0);
            iLGenerator.Emit(OpCodes.Ret);
            MethodInfo    setMethod        = baseType.GetMethod("SetValue").MakeGenericMethod(new Type[] { property.PropertyType });
            MethodBuilder setMethodBuilder = builder.DefineMethod("set_" + property.PropertyName, attributes, null, new Type[] { property.PropertyType });
            ILGenerator   generator2       = setMethodBuilder.GetILGenerator();

            generator2.Emit(OpCodes.Nop);
            generator2.Emit(OpCodes.Ldarg_0);
            generator2.Emit(OpCodes.Ldstr, property.PropertyName);
            generator2.Emit(OpCodes.Ldarg_1);
            generator2.EmitCall(OpCodes.Call, setMethod, null);
            generator2.Emit(OpCodes.Nop);
            generator2.Emit(OpCodes.Ret);
            propertyBuilder.SetGetMethod(getMethodBuilder);
            propertyBuilder.SetSetMethod(setMethodBuilder);
        }
Exemple #2
0
        //这个方法就是把一个RuntimeModelMeta转换成更接近类结构的TypeMeta对象
        private TypeMeta GetTypeMetaFromModelMeta(RuntimeModelMeta meta)
        {
            TypeMeta typeMeta = new TypeMeta();

            //我们让所有的动态类型都继承自DynamicEntity类,这个类主要是为了方便属性数据的读取,具体代码看后面
            typeMeta.BaseType = typeof(DynamicEntity);
            typeMeta.TypeName = meta.ClassName;

            foreach (var item in meta.GetProperties())
            {
                TypeMeta.TypePropertyMeta pmeta = new TypeMeta.TypePropertyMeta();
                pmeta.PropertyName = item.PropertyName;
                //如果必须输入数据,我们在属性上增加RequireAttribute特性,这样方便我们进行数据验证
                if (item.IsRequired)
                {
                    TypeMeta.AttributeMeta am = new TypeMeta.AttributeMeta();
                    am.AttributeType  = typeof(RequiredAttribute);
                    am.Properties     = new string[] { "ErrorMessage" };
                    am.PropertyValues = new object[] { "请输入" + item.Name };
                    pmeta.AttributeMetas.Add(am);
                }

                if (item.ValueType == "string")
                {
                    pmeta.PropertyType = typeof(string);
                    TypeMeta.AttributeMeta am = new TypeMeta.AttributeMeta();
                    //增加长度验证特性
                    am.AttributeType        = typeof(StringLengthAttribute);
                    am.ConstructorArgTypes  = new Type[] { typeof(int) };
                    am.ConstructorArgValues = new object[] { item.Length };
                    am.Properties           = new string[] { "ErrorMessage" };
                    am.PropertyValues       = new object[] { item.Name + "长度不能超过" + item.Length.ToString() + "个字符" };

                    pmeta.AttributeMetas.Add(am);
                }
                else if (item.ValueType == "int")
                {
                    if (!item.IsRequired)
                    {
                        pmeta.PropertyType = typeof(int?);
                    }
                    else
                    {
                        pmeta.PropertyType = typeof(int);
                    }
                }
                else if (item.ValueType == "datetime")
                {
                    if (!item.IsRequired)
                    {
                        pmeta.PropertyType = typeof(DateTime?);
                    }
                    else
                    {
                        pmeta.PropertyType = typeof(DateTime);
                    }
                }
                else if (item.ValueType == "bool")
                {
                    if (!item.IsRequired)
                    {
                        pmeta.PropertyType = typeof(bool?);
                    }
                    else
                    {
                        pmeta.PropertyType = typeof(bool);
                    }
                }
                else if (item.ValueType == "timestamp")
                {
                    pmeta.PropertyType = typeof(byte[]);
                }
                typeMeta.PropertyMetas.Add(pmeta);
            }
            return(typeMeta);
        }