/// <summary> /// Add the specified <paramref name="profile" /> to the configuration /// </summary> /// <param name="profile">The profile to add to the configuration.</param> /// <returns> /// A fluent builder to configure comparison. /// </returns> public ConfigurationBuilder Profile(IEntityProfile profile) { var type = profile.EntityType; var classMapping = GetClassMap(type); profile.Register(classMapping); return(this); }
/// <summary> /// Generate assignment function from the provided member /// </summary> /// <param name="profiles"></param> /// <param name="profile"></param> /// <param name="exprs"></param> /// <typeparam name="T"></typeparam> /// <returns></returns> public static Action <T, T> GenerateAssignment <T>(IEnumerable <IEntityProfile> profiles, IEntityProfile profile, IEnumerable <Expression <Func <T, object> > > exprs) { var entityExpr = Expression.Parameter(profile.Type); var dtoExpr = Expression.Parameter(profile.Type); var assignments = exprs .DistinctBy(x => x) .Select(x => new MemberExpressionVisitor(x).ResolveMemberInfo()) .Select(memberInfo => { var propertyInfo = (PropertyInfo)memberInfo; var memberAccessExprEntity = Expression.MakeMemberAccess(entityExpr, memberInfo); var memberAccessExprDto = Expression.MakeMemberAccess(dtoExpr, memberInfo); var existingAssignmentProfile = profiles.FirstOrDefault(x => x != profile && x.Type == propertyInfo.PropertyType); if (existingAssignmentProfile != null) { var genericUpdatorWithComparer = UpdatePropertyWithComparerMethodInfo.MakeGenericMethod(propertyInfo.PropertyType); var profileComparerExpr = Expression.Constant(existingAssignmentProfile.ComparerMethodInfo); var updateFuncExpr = Expression.Call( genericUpdatorWithComparer, memberAccessExprEntity, memberAccessExprDto, profileComparerExpr); return((Expression)updateFuncExpr); } else { var genericUpdatorWithoutComparer = UpdatePropertyWithoutComparerMethodInfo.MakeGenericMethod(propertyInfo.PropertyType); var setterMethodInfo = propertyInfo.GetSetMethod(); if (setterMethodInfo == null) { throw new Exception($"Setter for member: {memberInfo.Name} does not exist"); } var updateFuncExpr = Expression.Call( genericUpdatorWithoutComparer, memberAccessExprEntity, memberAccessExprDto ); var castRsltExpr = Expression.Convert(updateFuncExpr, propertyInfo.PropertyType); var assignmentExpr = Expression.Call(entityExpr, setterMethodInfo, castRsltExpr); return(assignmentExpr); } }); var body = Expression.Block(assignments); var lambda = Expression.Lambda <Action <T, T> >(body, entityExpr, dtoExpr); return(lambda.Compile()); }