首页 > 学院 > 开发设计 > 正文

Emit技术使用实例及应用思路

2019-11-17 02:49:53
字体:
来源:转载
供稿:网友

Emit技术使用实例及应用思路

System.Reflection.Emit提供了动态创建类并生成程序集的功能。 适用于.NET Framework 2.0及其以后的版本。

动态生成类在对于O/R Mapping来说有很大的作用,在实际应用中用到的一些场景,比如支持用户自定义字段,自定义公式的解析、动态插件等等。

下面就详细介绍一下Emit的实际应用:

 

Emit动态创建类型

目标:创建类型Employee,两个简单属性:Name(姓名),BirthDate(生日) ,一个方法void PRopertyChanged(string propertyName)

其中Name必填,预设值“新同事”,String类型;BirthDate是日期类型

 

准备工作:定义类型EntityDictionary和DynamicField,用于动态产生实体类型。

 

public class EntityDictionary {        private string _name;        /// <summary>        /// 实体名称        /// </summary>        public string Name {            get { return _name; }            set { _name = value; }        }        private string _caption;        /// <summary>        /// 显示值        /// </summary>        public string Caption {            get { return _caption; }            set { _caption = value; }        }        private List<string> _interfaceList;        /// <summary>        /// 接口列表        /// </summary>        public List<string> InterfaceList {            get { return _interfaceList; }            set { _interfaceList = value; }        }        private List<DynamicField> _dynamicFieldList;        /// <summary>        /// 字段列表        /// </summary>        public List<DynamicField> DynamicFieldList {            get { return _dynamicFieldList; }            set { _dynamicFieldList = value; }        }    }

 

 

public class DynamicField {        private string _name;        /// <summary>        /// 字段名称        /// </summary>        public string Name {            get { return _name; }            set { _name = value; }        }        private string _entityName;        /// <summary>        /// 实体名称        /// </summary>        public string EntityName {            get { return _entityName; }            set { _entityName = value; }        }        private string _type;        /// <summary>        /// 类型        /// </summary>        public string Type {            get { return _type; }            set { _type = value; }        }        private int _size;        /// <summary>        /// 长度        /// </summary>        public int Size {            get { return _size; }            set { _size = value; }        }        private byte _scale;        /// <summary>        /// 小数位数        /// </summary>        public byte Scale {            get { return _scale; }            set { _scale = value; }        }        private string _refType;        /// <summary>        /// 引用类型        /// </summary>        public string RefType {            get { return _refType; }            set { _refType = value; }        }        private string _control;        /// <summary>        /// 显示控件类型        /// </summary>        public string Control {            get { return _control; }            set { _control = value; }        }        private string _caption;        /// <summary>        /// 显示值        /// </summary>        public string Caption {            get { return _caption; }            set { _caption = value; }        }        private bool _isRequired;        /// <summary>        /// 是否必填        /// </summary>        public bool IsRequired {            get { return _isRequired; }            set { _isRequired = value; }        }        private string _defaultValue;        /// <summary>        /// 默认值        /// </summary>        public string DefaultValue {            get { return _defaultValue; }            set { _defaultValue = value; }        }        private string _externInfo;        /// <summary>        /// 扩展信息        /// </summary>        public string ExternInfo {            get { return _externInfo; }            set { _externInfo = value; }        }        private object _tempProperty;        /// <summary>        /// 保留栏位        /// </summary>        public object TempProperty {            get { return _tempProperty; }            set { _tempProperty = value; }        }    }

 

1.创建类

 

首先我们看下产生dll的代码:

public void Create() {            AppDomain myDomain = Thread.GetDomain();            AssemblyName myAsmName = new AssemblyName();            myAsmName.Name = "TestDynamicAssembly";            myAsmName.Version = new Version("1.0.0.0");            
         //创建一个永久程序集,设置为AssemblyBuilderaccess.RunAndSave。              AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(myAsmName,                                                            AssemblyBuilderAccess.RunAndSave);            //设置版本号信息            myAsmBuilder.DefineVersionInfoResource("Test", myAsmName.Version.ToString(), "TestCorp", "Copyright © TestCorp Limited 2014", "");             //创建一个永久单模程序块。               ModuleBuilder myModBuilder =                myAsmBuilder.DefineDynamicModule(myAsmName.Name, myAsmName.Name + ".dll");            //通常采用xml读取方式给DynamicField的属性赋值,这里Demo采用简单的直接赋值方式            List<DynamicField> listDynamicField = new List<DynamicField>();            DynamicField df = new DynamicField();            df = new DynamicField();            df.Name = "Name";            df.Caption = "姓名";            df.Type = "System.String";            df.IsRequired = true;//是否必填            df.DefaultValue = "新同事";//预设值            df.Size = 200;//字段长度            listDynamicField.Add(df);                        df.Name = "BirthDate";            df.Caption = "生日";            df.Type = "System.DateTime";            listDynamicField.Add(df);            //通常采用Xml读取方式给EntityDictionary的属性赋值,这里Demo采用简单的直接赋值方式            EntityDictionary ed = new EntityDictionary();            ed.Name = "Employee";            ed.Caption = "雇员信息";            ed.DynamicFieldList = listDynamicField;
        //创建类型            CreateEntity(myModBuilder, ed);
       //创建方法          AddMethordToTypeBuilder(myModBuilder);            //保存程序集。               myAsmBuilder.Save(myAsmName.Name + ".dll");        }

 

 

主要代码CreateEntity(创建类型)如下:

 

private void CreateEntity(ModuleBuilder myModBuilder, EntityDictionary ed) {            //重写命名空间            string typeName = string.Format("{0}.{1}", "TestDemo.DataEntity", ed.Name);            //创建TypeBuilder。               TypeBuilder myTypeBuilder = myModBuilder.DefineType(typeName,                                                            TypeAttributes.Public);            #region 类标记            //序列化            CustomAttributeBuilder customAttributeBuilder = new CustomAttributeBuilder(typeof(SerializableAttribute).GetConstructor(Type.EmptyTypes), new Type[] { });            myTypeBuilder.SetCustomAttribute(customAttributeBuilder);            //这是个相对复杂的类型标记 定义了类型的主键和别名,有兴趣可以研究一下            //if (!string.IsNullOrEmpty(df.Alias)) {            //    customAttributeBuilder = new CustomAttributeBuilder(typeof(DataEntityAttribute).GetConstructor(Type.EmptyTypes), new Type[] { }, new PropertyInfo[] { typeof(DataEntityAttribute).GetProperty("PrimaryKey"), typeof(DataEntityAttribute).GetProperty("Alias") }, new object[] { df.PrimaryKey, df.Alias });            //} else {            //    customAttributeBuilder = new CustomAttributeBuilder(typeof(DataEntityAttribute).GetConstructor(Type.EmptyTypes), new Type[] { }, new PropertyInfo[] { typeof(DataEntityAttribute).GetProperty("PrimaryKey") }, new object[] { df.PrimaryKey });            //}            //myTypeBuilder.SetCustomAttribute(customAttributeBuilder);            #endregion            #region 接口            //对类型添加接口            //if (df.InterfaceList != null &&
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表