예제 #1
0
        /// <summary>
        /// Creates the member bindings for the given <see cref="ClassMap"/>.
        /// </summary>
        /// <param name="mapping">The mapping to create the bindings for.</param>
        /// <param name="recordType">The type of record.</param>
        /// <param name="bindings">The bindings that will be added to from the mapping.</param>
        public virtual void CreateMemberBindingsForMapping(ClassMap mapping, Type recordType, List <MemberBinding> bindings)
        {
            foreach (var memberMap in mapping.MemberMaps)
            {
                var fieldExpression = CreateGetFieldExpression(memberMap);
                if (fieldExpression == null)
                {
                    continue;
                }

                bindings.Add(Expression.Bind(memberMap.Data.Member, fieldExpression));
            }

            foreach (var referenceMap in mapping.ReferenceMaps)
            {
                if (!reader.CanRead(referenceMap))
                {
                    continue;
                }

                var referenceBindings = new List <MemberBinding>();
                CreateMemberBindingsForMapping(referenceMap.Data.Mapping, referenceMap.Data.Member.MemberType(), referenceBindings);

                // This is in case an IContractResolver is being used.
                var type          = ReflectionHelper.CreateInstance(referenceMap.Data.Member.MemberType()).GetType();
                var referenceBody = Expression.MemberInit(Expression.New(type), referenceBindings);

                bindings.Add(Expression.Bind(referenceMap.Data.Member, referenceBody));
            }
        }
예제 #2
0
        /// <summary>
        /// Creates the member assignments for the given <see cref="ClassMap"/>.
        /// </summary>
        /// <param name="mapping">The mapping to create the assignments for.</param>
        /// <param name="assignments">The assignments that will be added to from the mapping.</param>
        public virtual void CreateMemberAssignmentsForMapping(ClassMap mapping, List <MemberAssignment> assignments)
        {
            foreach (var memberMap in mapping.MemberMaps)
            {
                var fieldExpression = CreateGetFieldExpression(memberMap);
                if (fieldExpression == null)
                {
                    continue;
                }

                assignments.Add(Expression.Bind(memberMap.Data.Member, fieldExpression));
            }

            foreach (var referenceMap in mapping.ReferenceMaps)
            {
                if (!reader.CanRead(referenceMap))
                {
                    continue;
                }

                var referenceAssignments = new List <MemberAssignment>();
                CreateMemberAssignmentsForMapping(referenceMap.Data.Mapping, referenceAssignments);

                var referenceBody = CreateInstanceAndAssignMembers(referenceMap.Data.Member.MemberType(), referenceAssignments);

                assignments.Add(Expression.Bind(referenceMap.Data.Member, referenceBody));
            }
        }
예제 #3
0
        /// <summary>
        /// Creates the member bindings for the given <see cref="ClassMap"/>.
        /// </summary>
        /// <param name="mapping">The mapping to create the bindings for.</param>
        /// <param name="recordType">The type of record.</param>
        /// <param name="bindings">The bindings that will be added to from the mapping.</param>
        public virtual void CreateMemberBindingsForMapping(ClassMap mapping, Type recordType, List <MemberBinding> bindings)
        {
            foreach (var memberMap in mapping.MemberMaps)
            {
                var fieldExpression = CreateGetFieldExpression(memberMap);
                if (fieldExpression == null)
                {
                    continue;
                }

                bindings.Add(Expression.Bind(memberMap.Data.Member, fieldExpression));
            }

            foreach (var referenceMap in mapping.ReferenceMaps)
            {
                if (!reader.CanRead(referenceMap))
                {
                    continue;
                }

                var referenceBindings = new List <MemberBinding>();
                CreateMemberBindingsForMapping(referenceMap.Data.Mapping, referenceMap.Data.Member.MemberType(), referenceBindings);

                Expression referenceBody;
                var        constructorExpression = referenceMap.Data.Mapping.Constructor;
                if (constructorExpression is NewExpression)
                {
                    referenceBody = Expression.MemberInit((NewExpression)constructorExpression, referenceBindings);
                }
                else if (constructorExpression is MemberInitExpression)
                {
                    var memberInitExpression = (MemberInitExpression)constructorExpression;
                    var defaultBindings      = memberInitExpression.Bindings.ToList();
                    defaultBindings.AddRange(referenceBindings);
                    referenceBody = Expression.MemberInit(memberInitExpression.NewExpression, defaultBindings);
                }
                else
                {
                    // This is in case an IContractResolver is being used.
                    var type = ReflectionHelper.CreateInstance(referenceMap.Data.Member.MemberType()).GetType();
                    referenceBody = Expression.MemberInit(Expression.New(type), referenceBindings);
                }

                bindings.Add(Expression.Bind(referenceMap.Data.Member, referenceBody));
            }
        }
예제 #4
0
        /// <summary>
        /// Creates the member assignments for the given <see cref="ClassMap"/>.
        /// </summary>
        /// <param name="mapping">The mapping to create the assignments for.</param>
        /// <param name="assignments">The assignments that will be added to from the mapping.</param>
        public virtual void CreateMemberAssignmentsForMapping(ClassMap mapping, List <MemberAssignment> assignments)
        {
            foreach (var memberMap in mapping.MemberMaps)
            {
                var fieldExpression = CreateGetFieldExpression(memberMap);
                if (fieldExpression == null)
                {
                    continue;
                }

                assignments.Add(Expression.Bind(memberMap.Data.Member, fieldExpression));
            }

            foreach (var referenceMap in mapping.ReferenceMaps)
            {
                if (!reader.CanRead(referenceMap))
                {
                    continue;
                }

                Expression referenceBody;
                if (referenceMap.Data.Mapping.ParameterMaps.Count > 0)
                {
                    var arguments = new List <Expression>();
                    CreateConstructorArgumentExpressionsForMapping(referenceMap.Data.Mapping, arguments);
                    var args = new GetConstructorArgs
                    {
                        ClassType = referenceMap.Data.Mapping.ClassType,
                    };
                    referenceBody = Expression.New(reader.Configuration.GetConstructor(args), arguments);
                }
                else
                {
                    var referenceAssignments = new List <MemberAssignment>();
                    CreateMemberAssignmentsForMapping(referenceMap.Data.Mapping, referenceAssignments);
                    referenceBody = CreateInstanceAndAssignMembers(referenceMap.Data.Member.MemberType(), referenceAssignments);
                }

                assignments.Add(Expression.Bind(referenceMap.Data.Member, referenceBody));
            }
        }
예제 #5
0
        /// <summary>
        /// Creates the action delegate used to hydrate a record's members with data from the reader.
        /// </summary>
        /// <typeparam name="T">The record type.</typeparam>
        protected virtual Action <T> CreateHydrateRecordAction <T>()
        {
            var recordType = typeof(T);

            if (reader.Context.ReaderConfiguration.Maps[recordType] == null)
            {
                reader.Context.ReaderConfiguration.Maps.Add(reader.Context.ReaderConfiguration.AutoMap(recordType));
            }

            var mapping = reader.Context.ReaderConfiguration.Maps[recordType];

            var recordTypeParameter = Expression.Parameter(recordType, "record");
            var memberAssignments   = new List <Expression>();

            foreach (var memberMap in mapping.MemberMaps)
            {
                var fieldExpression = expressionManager.CreateGetFieldExpression(memberMap);
                if (fieldExpression == null)
                {
                    continue;
                }

                var memberTypeParameter = Expression.Parameter(memberMap.Data.Member.MemberType(), "member");
                var memberAccess        = Expression.MakeMemberAccess(recordTypeParameter, memberMap.Data.Member);
                var memberAssignment    = Expression.Assign(memberAccess, fieldExpression);
                memberAssignments.Add(memberAssignment);
            }

            foreach (var referenceMap in mapping.ReferenceMaps)
            {
                if (!reader.CanRead(referenceMap))
                {
                    continue;
                }

                var referenceBindings = new List <MemberBinding>();
                expressionManager.CreateMemberBindingsForMapping(referenceMap.Data.Mapping, referenceMap.Data.Member.MemberType(), referenceBindings);

                // This is in case an IContractResolver is being used.
                var type          = ReflectionHelper.CreateInstance(referenceMap.Data.Member.MemberType()).GetType();
                var referenceBody = Expression.MemberInit(Expression.New(type), referenceBindings);

                var memberTypeParameter = Expression.Parameter(referenceMap.Data.Member.MemberType(), "referenceMember");
                var memberAccess        = Expression.MakeMemberAccess(recordTypeParameter, referenceMap.Data.Member);
                var memberAssignment    = Expression.Assign(memberAccess, referenceBody);
                memberAssignments.Add(memberAssignment);
            }

            var body = Expression.Block(memberAssignments);

            return(Expression.Lambda <Action <T> >(body, recordTypeParameter).Compile());
        }
예제 #6
0
        /// <summary>
        /// Creates the action delegate used to hydrate a record's members with data from the reader.
        /// </summary>
        /// <typeparam name="T">The record type.</typeparam>
        protected virtual Action <T> CreateHydrateRecordAction <T>()
        {
            var recordType = typeof(T);

            if (reader.Context.Maps[recordType] == null)
            {
                reader.Context.Maps.Add(reader.Context.AutoMap(recordType));
            }

            var mapping = reader.Context.Maps[recordType];

            var recordTypeParameter = Expression.Parameter(recordType, "record");
            var memberAssignments   = new List <Expression>();

            foreach (var memberMap in mapping.MemberMaps)
            {
                var fieldExpression = expressionManager.CreateGetFieldExpression(memberMap);
                if (fieldExpression == null)
                {
                    continue;
                }

                var memberTypeParameter = Expression.Parameter(memberMap.Data.Member.MemberType(), "member");
                var memberAccess        = Expression.MakeMemberAccess(recordTypeParameter, memberMap.Data.Member);
                var memberAssignment    = Expression.Assign(memberAccess, fieldExpression);
                memberAssignments.Add(memberAssignment);
            }

            foreach (var referenceMap in mapping.ReferenceMaps)
            {
                if (!reader.CanRead(referenceMap))
                {
                    continue;
                }

                var referenceAssignments = new List <MemberAssignment>();
                expressionManager.CreateMemberAssignmentsForMapping(referenceMap.Data.Mapping, referenceAssignments);

                var referenceBody = expressionManager.CreateInstanceAndAssignMembers(referenceMap.Data.Member.MemberType(), referenceAssignments);

                var memberTypeParameter = Expression.Parameter(referenceMap.Data.Member.MemberType(), "referenceMember");
                var memberAccess        = Expression.MakeMemberAccess(recordTypeParameter, referenceMap.Data.Member);
                var memberAssignment    = Expression.Assign(memberAccess, referenceBody);
                memberAssignments.Add(memberAssignment);
            }

            var body = Expression.Block(memberAssignments);

            return(Expression.Lambda <Action <T> >(body, recordTypeParameter).Compile());
        }