/// <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)); } }
/// <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)); } }
/// <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)); } }
/// <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)); } }
/// <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()); }
/// <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()); }