public static ConverterConfigurator <TSourceRoot, TSourceChild, TDestRoot, TDestChild, TDestValue> NullifyIf <TSourceRoot, TSourceChild, TDestRoot, TDestChild, TDestValue>( this ConverterConfigurator <TSourceRoot, TSourceChild, TDestRoot, TDestChild, TDestValue> configurator, Expression <Func <TDestChild, bool?> > condition) { configurator.SetMutator(NullifyIfConfiguration.Create(condition)); return(configurator); }
public static ConverterConfigurator <TSourceRoot, TSourceChild, TDestRoot, TDestChild, TTarget> Set <TSourceRoot, TSourceChild, TDestRoot, TDestChild, TTarget>( this ConverterConfigurator <TSourceRoot, TSourceChild, TDestRoot, TDestChild, TTarget> configurator, Expression <Func <TSourceChild, TTarget> > value) { var pathToSourceChild = (Expression <Func <TSourceRoot, TSourceChild> >)configurator.PathToSourceChild.ReplaceEachWithCurrent(); LambdaExpression valueFromRoot = pathToSourceChild.Merge(value); configurator.SetMutator(EqualsToConfiguration.Create(configurator.Root.ConfiguratorType, typeof(TDestRoot), valueFromRoot, null)); return(configurator); }
public static ConverterConfigurator <TSourceRoot, TSourceChild, TDestRoot, TDestChild, TTarget> Set <TSourceRoot, TSourceChild, TDestRoot, TDestChild, TTarget>( this ConverterConfigurator <TSourceRoot, TSourceChild, TDestRoot, TDestChild, TTarget> configurator, Expression <Func <TSourceChild, TTarget> > value) { var methodReplacer = new MethodReplacer(MutatorsHelperFunctions.EachMethod, MutatorsHelperFunctions.CurrentMethod); var pathToSourceChild = (Expression <Func <TSourceRoot, TSourceChild> >)methodReplacer.Visit(configurator.PathToSourceChild); LambdaExpression valueFromRoot = pathToSourceChild.Merge(value); configurator.SetMutator(EqualsToConfiguration.Create(typeof(TDestRoot), valueFromRoot, null)); return(configurator); }
public static ConverterConfigurator <TSourceRoot, TSourceChild, TDestRoot, TDestChild, TDestValue> Set <TSourceRoot, TSourceChild, TSourceNode, TSourceValue, TDestRoot, TDestChild, TDestValue>( this ConverterConfigurator <TSourceRoot, TSourceChild, TDestRoot, TDestChild, TDestValue> configurator, Expression <Func <TSourceChild, TSourceNode> > node, Expression <Func <TSourceNode, TSourceValue> > value, Expression <Func <TSourceValue, TDestValue> > converter, Expression <Func <TSourceNode, ValidationResult> > validator, int priority = 0) { var pathToSourceChild = (Expression <Func <TSourceRoot, TSourceChild> >)configurator.PathToSourceChild.ReplaceEachWithCurrent(); var nodeFromRoot = pathToSourceChild.Merge(node); var valueFromRoot = nodeFromRoot.Merge(value); var convertedValue = converter == null ? (LambdaExpression)valueFromRoot : valueFromRoot.Merge(converter); var validatorConfiguration = validator == null ? null : StaticValidatorConfiguration.Create(MutatorsCreator.Sharp, "SetWithValidator", priority, null, nodeFromRoot, valueFromRoot, validator); configurator.SetMutator(EqualsToConfiguration.Create(configurator.Root.ConfiguratorType, typeof(TDestRoot), convertedValue, validatorConfiguration)); return(configurator); }
private void ConfigureCustomFields(ConverterConfigurator <TSource, TDest> configurator, LambdaExpression pathToSourceChild, LambdaExpression pathToDestChild, Func <Expression, bool> sourceCustomFieldFits, Func <Expression, bool> destCustomFieldFits) { var sourceChildType = pathToSourceChild.Body.Type; var destChildType = pathToDestChild.Body.Type; LambdaExpression pathToSourceCustomFieldsContainer; var sourceCustomFieldsContainer = FindCustomFieldsContainer(sourceChildType, out pathToSourceCustomFieldsContainer); var sourceCustomFields = FindCustomFields(sourceChildType, sourceCustomFieldFits, pathToSourceChild); LambdaExpression pathToDestCustomFieldsContainer; var destCustomFieldsContainer = FindCustomFieldsContainer(destChildType, out pathToDestCustomFieldsContainer); var destCustomFields = FindCustomFields(destChildType, destCustomFieldFits, pathToDestChild); var converterType = configurator.Root.ConfiguratorType; if (sourceCustomFields.Length > 0) { if (destCustomFields.Length > 0 || sourceCustomFieldsContainer != null) { throw new InvalidOperationException(); } if (destCustomFieldsContainer == null) { return; } var destParameter = pathToDestCustomFieldsContainer.Parameters.Single(); var indexerGetter = destCustomFieldsContainer.PropertyType.GetProperty("Item", BindingFlags.Public | BindingFlags.Instance).GetGetMethod(); foreach (var customField in sourceCustomFields) { var path = customField.Path; var rootProperty = customField.RootProperty; var titleType = customField.TitleType; var value = customField.Value; TypeCode typeCode; LambdaExpression convertedValue; if (stringConverter != null && stringConverter.CanConvert(value.Body.Type)) { typeCode = TypeCode.String; convertedValue = Expression.Lambda( Expression.Call(Expression.Constant(stringConverter, typeof(IStringConverter)), convertToStringMethod.MakeGenericMethod(value.Body.Type), Expression.Convert(value.Body, typeof(object))), value.Parameters); } else { typeCode = GetTypeCode(value.Body.Type); convertedValue = value; } if (rootProperty.PropertyType.IsArray && !IsALeaf(rootProperty.PropertyType)) { // An array of complex types var delimiterIndex = path.IndexOf('ё'); var pathToArray = path.Substring(0, delimiterIndex); var pathToLeaf = path.Substring(delimiterIndex + 1, path.Length - delimiterIndex - 1); var pathToTarget = pathToDestChild.Merge(Expression.Lambda(Expression.Call(pathToDestCustomFieldsContainer.Body, indexerGetter, Expression.Constant(pathToArray)), destParameter)).Body; configurator.SetMutator(Expression.Property(pathToTarget, "TypeCode"), EqualsToConfiguration.Create <TDest>(converterType, Expression.Lambda(Expression.Constant(TypeCode.Object)))); configurator.SetMutator(Expression.Property(pathToTarget, "IsArray"), EqualsToConfiguration.Create <TDest>(converterType, Expression.Lambda(Expression.Constant(true)))); var pathToDestArrayItem = Expression.Convert(Expression.Call(MutatorsHelperFunctions.EachMethod.MakeGenericMethod(typeof(object)), Expression.Convert(Expression.Property(pathToTarget, "Value"), typeof(object[]))), typeof(Hashtable)); var itemIndexerGetter = typeof(Hashtable).GetProperty("Item", BindingFlags.Public | BindingFlags.Instance).GetGetMethod(); var pathToDestArrayItemValue = Expression.Call(pathToDestArrayItem, itemIndexerGetter, Expression.Constant(pathToLeaf)); configurator.SetMutator(pathToDestArrayItemValue, EqualsToConfiguration.Create <TDest>(converterType, pathToSourceChild.Merge(convertedValue))); var pathToTypeCodes = Expression.Property(pathToTarget, "TypeCodes"); var pathToItemTypeCode = Expression.Call(pathToTypeCodes, pathToTypeCodes.Type.GetProperty("Item", BindingFlags.Public | BindingFlags.Instance).GetGetMethod(), Expression.Constant(pathToLeaf)); configurator.SetMutator(pathToItemTypeCode, EqualsToConfiguration.Create <TDest>(converterType, Expression.Lambda(Expression.Constant(typeCode)))); if (value.Body is MemberExpression) { var member = ((MemberExpression)value.Body).Member; var customFieldAttribute = member.GetCustomAttributes(typeof(CustomFieldAttribute), false).SingleOrDefault() as CustomFieldAttribute; if (customFieldAttribute != null && customFieldAttribute.TitleType != null) { var pathToTitles = Expression.Property(pathToTarget, "Titles"); var pathToItemTitle = Expression.Call(pathToTitles, pathToTitles.Type.GetProperty("Item", BindingFlags.Public | BindingFlags.Instance).GetGetMethod(), Expression.Constant(pathToLeaf)); configurator.SetMutator(pathToItemTitle, EqualsToConfiguration.Create <TDest>(converterType, Expression.Lambda(Expression.Constant(StaticMultiLanguageTextCache.Get(customFieldAttribute.TitleType))))); } } } else { var pathToTarget = pathToDestChild.Merge(Expression.Lambda(Expression.Call(pathToDestCustomFieldsContainer.Body, indexerGetter, Expression.Constant(path)), destParameter)).Body; configurator.SetMutator(Expression.Property(pathToTarget, "TypeCode"), EqualsToConfiguration.Create <TDest>(converterType, Expression.Lambda(Expression.Constant(typeCode)))); configurator.SetMutator(Expression.Property(pathToTarget, "IsArray"), EqualsToConfiguration.Create <TDest>(converterType, Expression.Lambda(Expression.Constant(convertedValue.Body.Type.IsArray)))); configurator.SetMutator(Expression.Property(pathToTarget, "Value"), EqualsToConfiguration.Create <TDest>(converterType, pathToSourceChild.Merge(convertedValue))); if (titleType != null) { configurator.SetMutator(Expression.Property(pathToTarget, "Title"), EqualsToConfiguration.Create <TDest>(converterType, Expression.Lambda(Expression.Constant(StaticMultiLanguageTextCache.Get(titleType))))); } } } } else if (destCustomFields.Length > 0) { if (destCustomFieldsContainer != null) { throw new InvalidOperationException(); } if (sourceCustomFieldsContainer == null) { return; } var sourceParameter = pathToSourceCustomFieldsContainer.Parameters.Single(); var indexerGetter = sourceCustomFieldsContainer.PropertyType.GetProperty("Item", BindingFlags.Public | BindingFlags.Instance).GetGetMethod(); foreach (var customField in destCustomFields) { var path = customField.Path; var rootProperty = customField.RootProperty; var pathToTarget = pathToDestChild.Merge(customField.Value).Body; if (rootProperty.PropertyType.IsArray && !IsALeaf(rootProperty.PropertyType.GetElementType())) { var delimiterIndex = path.IndexOf('ё'); var pathToArray = path.Substring(0, delimiterIndex); var pathToLeaf = path.Substring(delimiterIndex + 1, path.Length - delimiterIndex - 1); Expression value = Expression.Property(Expression.Call(pathToSourceCustomFieldsContainer.Body, indexerGetter, Expression.Constant(pathToArray)), "Value"); value = Expression.Convert(Expression.Call(MutatorsHelperFunctions.EachMethod.MakeGenericMethod(typeof(object)), Expression.Convert(value, typeof(object[]))), typeof(Hashtable)); value = Expression.Call(value, typeof(Hashtable).GetProperty("Item", BindingFlags.Public | BindingFlags.Instance).GetGetMethod(), Expression.Constant(pathToLeaf)); var convertedValue = MakeConvert(value, pathToTarget.Type); configurator.SetMutator(pathToTarget, EqualsToConfiguration.Create <TDest>(converterType, pathToSourceChild.Merge(Expression.Lambda(convertedValue, sourceParameter)))); } else { Expression value = Expression.Property(Expression.Call(pathToSourceCustomFieldsContainer.Body, indexerGetter, Expression.Constant(path)), "Value"); var convertedValue = MakeConvert(value, pathToTarget.Type); configurator.SetMutator(pathToTarget, EqualsToConfiguration.Create <TDest>(converterType, pathToSourceChild.Merge(Expression.Lambda(convertedValue, sourceParameter)))); } } } else { if (sourceCustomFieldsContainer == null || destCustomFieldsContainer == null) { return; } var destParameter = pathToDestCustomFieldsContainer.Parameters.Single(); var sourceParameter = pathToSourceCustomFieldsContainer.Parameters.Single(); Expression pathToDestCustomContainer = Expression.Call(MutatorsHelperFunctions.EachMethod.MakeGenericMethod(destCustomFieldsContainer.PropertyType.GetItemType()), pathToDestCustomFieldsContainer.Body); Expression pathToSourceCustomContainer = Expression.Call(MutatorsHelperFunctions.EachMethod.MakeGenericMethod(sourceCustomFieldsContainer.PropertyType.GetItemType()), pathToSourceCustomFieldsContainer.Body); var pathToTarget = pathToDestChild.Merge(Expression.Lambda(Expression.Property(pathToDestCustomContainer, "Key"), destParameter)).Body; Expression value = Expression.Property(pathToSourceCustomContainer, "Key"); configurator.SetMutator(pathToTarget, EqualsToConfiguration.Create <TDest>(converterType, pathToSourceChild.Merge(Expression.Lambda(value, sourceParameter)))); value = Expression.Property(pathToSourceCustomContainer, "Value"); pathToTarget = pathToDestChild.Merge(Expression.Lambda(Expression.Property(pathToDestCustomContainer, "Value"), destParameter)).Body; configurator.SetMutator(Expression.Property(pathToTarget, "TypeCode"), EqualsToConfiguration.Create <TDest>(converterType, pathToSourceChild.Merge(Expression.Lambda(Expression.Property(value, "TypeCode"), sourceParameter)))); configurator.SetMutator(Expression.Property(pathToTarget, "TypeCodes"), EqualsToConfiguration.Create <TDest>(converterType, pathToSourceChild.Merge(Expression.Lambda(Expression.Property(value, "TypeCodes"), sourceParameter)))); configurator.SetMutator(Expression.Property(pathToTarget, "Titles"), EqualsToConfiguration.Create <TDest>(converterType, pathToSourceChild.Merge(Expression.Lambda(Expression.Property(value, "Titles"), sourceParameter)))); configurator.SetMutator(Expression.Property(pathToTarget, "IsArray"), EqualsToConfiguration.Create <TDest>(converterType, pathToSourceChild.Merge(Expression.Lambda(Expression.Property(value, "IsArray"), sourceParameter)))); configurator.SetMutator(Expression.Property(pathToTarget, "Value"), EqualsToConfiguration.Create <TDest>(converterType, pathToSourceChild.Merge(Expression.Lambda(Expression.Property(value, "Value"), sourceParameter)))); configurator.SetMutator(Expression.Property(pathToTarget, "Title"), EqualsToConfiguration.Create <TDest>(converterType, pathToSourceChild.Merge(Expression.Lambda(Expression.Property(value, "Title"), sourceParameter)))); } }