예제 #1
0
        /// <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));
        }
예제 #2
0
        /// <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;
        }