private void ConfigureCustomFields(ConverterConfigurator <TSource, TDest> configurator) { var sourceParameter = Expression.Parameter(typeof(TSource)); var destParameter = Expression.Parameter(typeof(TDest)); var tree = configurator.GetTree(); var subNodes = new List <ModelConfigurationNode>(); tree.FindSubNodes(subNodes); var dependencies = from node in subNodes from mutator in node.GetMutators() where mutator is EqualsToConfiguration from dependency in ((EqualsToConfiguration)mutator).Value.ExtractPrimaryDependencies() select new ExpressionWrapper(dependency.Body, false); var hashset = new HashSet <ExpressionWrapper>(dependencies); Func <Expression, bool> sourceCustomFieldFits = path => !hashset.Contains(new ExpressionWrapper(path, false)); Func <Expression, bool> destCustomFieldFits = path => { var node = tree.Traverse(path, false); if (node == null) { return(true); } return(node.GetMutators().Length == 0); }; ConfigureCustomFields(configurator, Expression.Lambda(sourceParameter, sourceParameter), Expression.Lambda(destParameter, destParameter), sourceCustomFieldFits, destCustomFieldFits); ConfigureCustomFieldsForArrays(configurator, typeof(TDest), Expression.Lambda(destParameter, destParameter), sourceCustomFieldFits, destCustomFieldFits); }
private void ConfigureCustomFieldsForArrays(ConverterConfigurator <TSource, TDest> configurator, Type type, LambdaExpression pathToDestChild, Func <Expression, bool> sourceCustomFieldFits, Func <Expression, bool> destCustomFieldFits) { if (type == null || IsALeaf(type)) { return; } var tree = configurator.GetTree(); var properties = type.GetOrderedProperties(); var parameter = Expression.Parameter(type); foreach (var property in properties) { var pathToNextDestChild = pathToDestChild.Merge(Expression.Lambda(Expression.Property(parameter, property), parameter)); if (!property.PropertyType.IsArray) { ConfigureCustomFieldsForArrays(configurator, property.PropertyType, pathToNextDestChild, sourceCustomFieldFits, destCustomFieldFits); } else { var pathToDestArray = pathToNextDestChild.Body; var node = tree.Traverse(pathToDestArray, false); if (node == null) { continue; } var arrays = node.GetArrays(); if (!arrays.TryGetValue(typeof(TSource), out var pathToSourceArray)) { continue; } var pathToDestArrayItem = Expression.Call(MutatorsHelperFunctions.EachMethod.MakeGenericMethod(pathToDestArray.Type.GetItemType()), pathToDestArray); var pathToSourceArrayItem = Expression.Call(MutatorsHelperFunctions.EachMethod.MakeGenericMethod(pathToSourceArray.Type.GetItemType()), pathToSourceArray); ConfigureCustomFields(configurator, Expression.Lambda(pathToSourceArrayItem, pathToSourceArray.ExtractParameters()), Expression.Lambda(pathToDestArrayItem, pathToDestArray.ExtractParameters()), sourceCustomFieldFits, destCustomFieldFits); } } }