博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C# Emit动态代理生成一个实体对象
阅读量:4597 次
发布时间:2019-06-09

本文共 4331 字,大约阅读时间需要 14 分钟。

1   ///  2     /// 使用Emit动态代理收集实体信息 3     ///  4     /// 
实体类
5 public class TDynamicBuilder
6 { 7 #region 变量区域 8 private static readonly MethodInfo getValueMethod = typeof(IDataRecord).GetMethod("get_Item", new[] { typeof(int) }); 9 10 private static readonly MethodInfo isDBNullMethod = typeof(IDataRecord).GetMethod("IsDBNull", new[] { typeof(int) });11 12 private delegate T Load(IDataRecord dataRecord);13 14 ///
15 /// 代理16 /// 17 private Load Handler;//最终执行动态方法的一个委托 参数是IDataRecord接口18 #endregion19 20 #region 构造函数21 private TDynamicBuilder() { }22 #endregion23 24 #region +Build Emit动态代理生成一个实体对象25 ///
26 /// Emit动态代理生成一个实体对象27 /// 28 ///
DataReader接口实现对象29 ///
30 public T Build(IDataRecord dataRecord)31 {32 return Handler(dataRecord);//执行CreateBuilder里创建的DynamicCreate动态方法的委托33 }34 #endregion35 36 #region + CreateBuilder 创建一个Builder器37 ///
38 /// 创建一个Builder器39 /// 40 ///
DataReader接口实现对象41 ///
42 public static TDynamicBuilder
CreateBuilder(IDataRecord dataRecord)43 {44 var dynamicBuilder = new TDynamicBuilder
();45 var type = typeof(T);46 //定义一个名为DynamicCreate的动态方法,返回值typof(T),参数typeof(IDataRecord)47 var method = new DynamicMethod("DynamicCreate", type, new[] { typeof(IDataRecord) }, typeof(T), true);48 var generator = method.GetILGenerator();//创建一个MSIL生成器,为动态方法生成代码49 var result = generator.DeclareLocal(type);//声明指定类型的局部变量 可以T t;这么理解50 //The next piece of code instantiates the requested type of object and stores it in the local variable. 可以t=new T();这么理解51 generator.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes));52 generator.Emit(OpCodes.Stloc, result);53 var propertys = type.GetProperties();54 //数据集合55 for (var i = 0; i < dataRecord.FieldCount; i++)56 {57 //查找属性58 var propertyInfo = propertys.FirstOrDefault(a => string.Equals(a.Name.ToLower(), dataRecord.GetName(i).ToLower()));59 if (propertyInfo == null) continue;60 if (!string.Equals(propertyInfo.Name, dataRecord.GetName(i), StringComparison.CurrentCultureIgnoreCase)) continue;61 //根据列名取属性 原则上属性和列是一一对应的关系62 var endIfLabel = generator.DefineLabel();63 64 /*The code then loops through the fields in the data reader, finding matching properties on the type passed in. 65 * When a match is found, the code checks to see if the value from the data reader is null.66 */67 generator.Emit(OpCodes.Ldarg_0);68 generator.Emit(OpCodes.Ldc_I4, i);69 //就知道这里要调用IsDBNull方法 如果IsDBNull==true contine70 generator.Emit(OpCodes.Callvirt, isDBNullMethod);71 generator.Emit(OpCodes.Brtrue, endIfLabel);72 73 /*If the value in the data reader is not null, the code sets the value on the object.*/74 generator.Emit(OpCodes.Ldloc, result);75 generator.Emit(OpCodes.Ldarg_0);76 generator.Emit(OpCodes.Ldc_I4, i);77 generator.Emit(OpCodes.Callvirt, getValueMethod); //调用get_Item方法78 generator.Emit(OpCodes.Unbox_Any, dataRecord.GetFieldType(i));79 generator.Emit(OpCodes.Callvirt, propertyInfo.GetSetMethod()); //给该属性设置对应值80 81 generator.MarkLabel(endIfLabel);82 83 }84 85 /*The last part of the code returns the value of the local variable*/86 generator.Emit(OpCodes.Ldloc, result);87 generator.Emit(OpCodes.Ret);//方法结束,返回88 89 //完成动态方法的创建,并且创建执行该动态方法的委托,赋值到全局变量handler,handler在Build方法里Invoke90 dynamicBuilder.Handler = (Load)method.CreateDelegate(typeof(Load));91 return dynamicBuilder;92 }93 #endregion94 95 }

 

转载于:https://www.cnblogs.com/gaobing/p/5125198.html

你可能感兴趣的文章
Mac下多个jdk自由切换
查看>>
Android中onInterceptTouchEvent、dispatchTouchEvent及onTouchEvent的调用顺序及内部原理
查看>>
extension(类扩展)和 category(类别)
查看>>
Swift - 跑酷游戏开发(SpriteKit游戏开发)
查看>>
iOS 8 Metal Swift教程(一) :开始学习
查看>>
List接口源码解读
查看>>
GNU Radio入门之旅
查看>>
将数据库所有表和字段首字母变成大写
查看>>
如何在vue项目中使用md5.js及base64.js
查看>>
最长公共子序列 Lcs
查看>>
关于虚拟空间上传没有权限问题 只要更改一下system.web 就可以
查看>>
C#知识点总结【1】
查看>>
BZOJ 1257: [CQOI2007]余数之和
查看>>
20155235 2016-2017-2 《Java程序设计》第六周学习总结
查看>>
H3C VLAN 配置
查看>>
BZOJ 1077: [SCOI2008]天平
查看>>
第一天
查看>>
团队冲刺第十天
查看>>
Gradle用户指南
查看>>
iOS审核策略重磅更新:Guideline 2.1批量拒审
查看>>