/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="Instance"></typeparam> /// <param name="dataRecord"></param> /// <param name="memberName"></param> /// <returns></returns> public static T ReadingValueFromDataRecordTypeHandler <T, Instance>(System.Data.IDataRecord dataRecord, string memberName) { var attribute = TypeHandlerAttributeStorager <Instance> .Query(memberName); if (attribute == null) { return(default(T)); } return(attribute.OnDataReading <T>(dataRecord, memberName)); }
/// <summary> /// 对对象进行emit操作 /// </summary> /// <param name="emit">The emit.</param> public static void BuildObject(EasyEmitBuilder <Func <IDataRecord, T> > emit) { var type = typeof(T); var targetMembers = GetMembers(type); /*实例*/ var instanceLocal = emit.DeclareLocal(type); if (type.IsValueType) { if (targetMembers == null || targetMembers.Count == 0) { emit.LoadLocalAddress(instanceLocal); emit.InitializeObject(type); emit.LoadLocal(instanceLocal); emit.Return(); return; } emit.LoadLocalAddress(instanceLocal); emit.InitializeObject(type); emit.LoadLocal(instanceLocal); emit.StoreLocal(instanceLocal); goto _Read; } else { /*object*/ var ctors = typeof(T).GetConstructors(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic); foreach (var ctor in ctors) { if (ctor.GetParameters().Length == 0) { emit.NewObject(ctor); emit.StoreLocal(instanceLocal); if (targetMembers == null || targetMembers.Count == 0) { emit.LoadLocal(instanceLocal); emit.Return(); return; } goto _Read; } } throw new ArgumentException(string.Format("the type {0} can not find the no parameter of ctor method", typeof(T).FullName)); } _Read: { var locals = new[] { emit.DeclareLocal(typeof(bool)), emit.DeclareLocal(typeof(int)), }; var retlbl = emit.DefineLabel(); var labels = new List <ILabel>(targetMembers.Count); for (var i = 0; i < targetMembers.Count; i++) { labels.Add(emit.DefineLabel()); } for (var i = 0; i < targetMembers.Count; i++) { var member = targetMembers[i]; Type memberType = member.MemberType == MemberTypes.Property ? ((PropertyInfo)member).PropertyType : ((FieldInfo)member).FieldType; if (i > 0) { emit.MarkLabel(labels[i]); } var attribute = member.GetCustomAttribute <TypeHandlerAttribute>(); if (attribute != null && attribute.TypeHandler.IsAssignableFromType(typeof(IReadingFromDataRecordToValueTypeHandler <>))) { TypeHandlerAttributeStorager <T> .Storage(attribute, member.Name); if (type.IsValueType) { emit.LoadLocalAddress(instanceLocal); } else { emit.LoadLocal(instanceLocal); } emit.LoadArgument(0); emit.LoadConstant(member.Name); if (member.MemberType == MemberTypes.Property) { emit.Call(typeof(DataRecordBuilderHelper).GetMethod("ReadingValueFromDataRecordTypeHandler").MakeGenericMethod(new[] { ((PropertyInfo)member).PropertyType, type })); emit.Call(((PropertyInfo)member).GetSetMethod(true)); } else { emit.Call(typeof(DataRecordBuilderHelper).GetMethod("ReadingValueFromDataRecordTypeHandler").MakeGenericMethod(new[] { ((FieldInfo)member).FieldType, type })); emit.StoreField(((FieldInfo)member)); } if (i < labels.Count - 1) { emit.Branch(labels[i + 1]); } else { emit.Branch(retlbl); } continue; } /*reader*/ emit.LoadArgument(0); emit.LoadConstant(member.Name); emit.Call(DataRecordBuilderHelper._mGetOrdinal); emit.StoreLocal(locals[1]); emit.LoadLocal(locals[1]); emit.LoadConstant(0); if (i < labels.Count - 1) { emit.BranchIfLess(labels[i + 1]); } else { emit.BranchIfLess(retlbl); } emit.LoadArgument(0); emit.LoadLocal(locals[1]); emit.Call(DataRecordBuilderHelper._mIsDBNull); emit.StoreLocal(locals[0]); emit.LoadLocal(locals[0]); if (i < labels.Count - 1) { emit.BranchIfTrue(labels[i + 1]); } else { emit.BranchIfTrue(retlbl); } if (DataRecordBuilderHelper.DefinedTypeDict.ContainsKey(memberType)) { if (type.IsValueType) { emit.LoadLocalAddress(instanceLocal); } else { emit.LoadLocal(instanceLocal); } emit.LoadArgument(0); emit.LoadLocal(locals[1]); emit.Call(DataRecordBuilderHelper.DefinedTypeDict[memberType]); if (member.MemberType == MemberTypes.Property) { emit.Call(((PropertyInfo)member).GetSetMethod(true)); } else { emit.StoreField(((FieldInfo)member)); } if (i < labels.Count - 1) { emit.Branch(labels[i + 1]); } else { emit.Branch(retlbl); } continue; } else if (memberType.IsEnum) { if (type.IsValueType) { emit.LoadLocalAddress(instanceLocal); } else { emit.LoadLocal(instanceLocal); } emit.LoadArgument(0); emit.LoadLocal(locals[1]); var underlyingType = Enum.GetUnderlyingType(memberType); emit.Call(DataRecordBuilderHelper.DefinedTypeDict[underlyingType]); emit.Call(typeof(DataRecordBuilderHelper).GetMethod("_EnumParse", BindingFlags.NonPublic | BindingFlags.Static).MakeGenericMethod(new[] { memberType, underlyingType })); //emit.Call(DataRecordBuilderHelper.DefinedTypeDict[typeof(long)]); //emit.Call(typeof(DataRecordBuilderHelper).GetMethod("_EnumParse", BindingFlags.NonPublic | BindingFlags.Static).MakeGenericMethod(memberType)); if (member.MemberType == MemberTypes.Property) { emit.Call(((PropertyInfo)member).GetSetMethod(true)); } else { emit.StoreField(((FieldInfo)member)); } if (i < labels.Count - 1) { emit.Branch(labels[i + 1]); } else { emit.Branch(retlbl); } continue; } else if (Nullable.GetUnderlyingType(memberType) != null) { var nullable = Nullable.GetUnderlyingType(memberType); if (nullable.IsEnum) { if (type.IsValueType) { emit.LoadLocalAddress(instanceLocal); } else { emit.LoadLocal(instanceLocal); } emit.LoadArgument(0); emit.LoadLocal(locals[1]); var underlyingType = Enum.GetUnderlyingType(nullable); emit.Call(DataRecordBuilderHelper.DefinedTypeDict[underlyingType]); emit.Call(typeof(DataRecordBuilderHelper).GetMethod("_EnumParse", BindingFlags.NonPublic | BindingFlags.Static).MakeGenericMethod(new[] { nullable, underlyingType })); //emit.Call(DataRecordBuilderHelper.DefinedTypeDict[typeof(long)]); //emit.Call(typeof(DataRecordBuilderHelper).GetMethod("_EnumParse", BindingFlags.NonPublic | BindingFlags.Static).MakeGenericMethod(nullable)); emit.NewObject(memberType, new[] { nullable }); if (member.MemberType == MemberTypes.Property) { emit.Call(((PropertyInfo)member).GetSetMethod(true)); } else { emit.StoreField(((FieldInfo)member)); } if (i < labels.Count - 1) { emit.Branch(labels[i + 1]); } else { emit.Branch(retlbl); } continue; } if (!DataRecordBuilderHelper.DefinedTypeDict.ContainsKey(nullable)) { continue; } if (type.IsValueType) { emit.LoadLocalAddress(instanceLocal); } else { emit.LoadLocal(instanceLocal); } emit.LoadArgument(0); emit.LoadLocal(locals[1]); emit.Call(DataRecordBuilderHelper.DefinedTypeDict[nullable]); emit.NewObject(memberType, new[] { nullable }); if (member.MemberType == MemberTypes.Property) { emit.Call(((PropertyInfo)member).GetSetMethod(true)); } else { emit.StoreField(((FieldInfo)member)); } if (i < labels.Count - 1) { emit.Branch(labels[i + 1]); } else { emit.Branch(retlbl); } continue; } else { emit.Nop(); } } emit.MarkLabel(retlbl); emit.LoadLocal(instanceLocal); emit.Return(); }; return; }