分享一个同事给的动态类生成工具

在MVVM开发模式中,xaml文件中的GridView是和Viewmodel中的某个对象集合ObserverCollection<T>相对应的,不多做解释,而这个对象T中的属性有可能是动态的,比如将CategoryName做为列名的情况等。这就需要我们动态的创建一个类,其中的属性是从数据库中提取出来的。让我们看看这个生成工具的实现,里面的一些代码不经常使用。

public class DynamicTypeTools
    {
        /// <summary>
        /// 属性类
        /// </summary>
        public class DynamicDetail
        {
            /// <summary>
            /// 属性数据类型
            /// </summary>
            public Type PropertyType { get; set; }
            /// <summary>
            /// 属性名称
            /// </summary>
            public string PropertyName { get; set; }
        }
        /// <summary>
        /// 动态创建类
        /// </summary>
        /// <param name="list">属性类集合</param>
        /// <returns>创建出来的类</returns>
        public static Type CreateClass(List<DynamicDetail> list)
        { 
            TypeBuilder tb = GetTypeBuilder(list.GetHashCode());
            ConstructorBuilder constructor =
                        tb.DefineDefaultConstructor(
                                    MethodAttributes.Public |
                                    MethodAttributes.SpecialName |
                                    MethodAttributes.RTSpecialName); 
            foreach(var item in list)
            {
                CreateProperty(tb, item.PropertyName, item.PropertyType);
            } 
            return tb.CreateType(); 
        }
        private static TypeBuilder GetTypeBuilder(int code)
        {
            AssemblyName an = new AssemblyName("TempAssembly" + code);
            AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, 
AssemblyBuilderAccess.Run);
            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
            TypeBuilder tb = moduleBuilder.DefineType("TempType" + code
                                , TypeAttributes.Public |
                                TypeAttributes.Class |
                                TypeAttributes.AutoClass |
                                TypeAttributes.AnsiClass |
                                TypeAttributes.BeforeFieldInit |
                                TypeAttributes.AutoLayout
                                , typeof(object));
            return tb;
        }

        private static void CreateProperty(TypeBuilder tb, string propertyName, Type propertyType)
        {
            FieldBuilder fieldBuilder = tb.DefineField("_" + propertyName, propertyType, FieldAttributes.Private);

            PropertyBuilder propertyBuilder = tb.DefineProperty(propertyName, 
PropertyAttributes.HasDefault, propertyType, null);
            MethodBuilder getPropMthdBldr =
                tb.DefineMethod("get_" + propertyName,
                    MethodAttributes.Public |
                    MethodAttributes.SpecialName |
                    MethodAttributes.HideBySig,
                    propertyType, Type.EmptyTypes);

            ILGenerator getIL = getPropMthdBldr.GetILGenerator();

            getIL.Emit(OpCodes.Ldarg_0);
            getIL.Emit(OpCodes.Ldfld, fieldBuilder);
            getIL.Emit(OpCodes.Ret);

            MethodBuilder setPropMthdBldr =
                tb.DefineMethod("set_" + propertyName,
                  MethodAttributes.Public |
                  MethodAttributes.SpecialName |
                  MethodAttributes.HideBySig,
                  null, new Type[] { propertyType });

            ILGenerator setIL = setPropMthdBldr.GetILGenerator();

            setIL.Emit(OpCodes.Ldarg_0);
            setIL.Emit(OpCodes.Ldarg_1);
            setIL.Emit(OpCodes.Stfld, fieldBuilder);
            setIL.Emit(OpCodes.Ret);

            propertyBuilder.SetGetMethod(getPropMthdBldr);
            propertyBuilder.SetSetMethod(setPropMthdBldr);
        }
    }
这个类中有一个静态方法和一个属性的Model类,简单介绍一下Type CreateClass(List<DynamicDetail> list) 这个方法,DynamicDetail这个
类中有两个属性,一个是动态类的属性名称,一个是动态类的属性类型,在创建动态类的时候只需要给CreateClass方法传递一个DynamicDetail
的集合,就可以返回一个创建好的类了。使用方法是:
image

下载地址:http://files.cnblogs.com/wengyuli/DynamicTypeTools.rar

posted @ 2011-05-12 21:57 翁玉礼 阅读(...) 评论(...) 编辑 收藏