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);
 }
Example #2
0
        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);
        }
Example #4
0
        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))));
            }
        }