/// <summary>
        ///     Second part of the rule declaration; specifies the function that will compute the value of the target property
        /// </summary>
        /// <typeparam name="TParent"></typeparam>
        /// <typeparam name="TTargetProperty"></typeparam>
        /// <param name="token"></param>
        /// <param name="valueComputer"></param>
        /// <returns></returns>
        public static FluentToken <TParent, TTargetProperty> With <TParent, TTargetProperty>(
            this FluentToken <TParent, TTargetProperty> token, Expression <Func <TParent, TTargetProperty> > valueComputer)
        {
            token.ValueComputer = valueComputer.Compile();

            return(token);
        }
        /// <summary>
        ///     Specifies an optional applicability condition as a predicate; if false the rule will not be triggered
        /// </summary>
        /// <typeparam name="TParent"></typeparam>
        /// <typeparam name="TTargetProperty"></typeparam>
        /// <param name="token"></param>
        /// <param name="ifPredicate"></param>
        /// <returns></returns>
        public static FluentToken <TParent, TTargetProperty> If <TParent, TTargetProperty>(
            this FluentToken <TParent, TTargetProperty> token, Predicate <TParent> ifPredicate)
        {
            token.IfPredicate = ifPredicate;

            return(token);
        }
Ejemplo n.º 3
0
        /// <summary>
        ///     Specifies an extra trigger property. Multiple statements may be chained
        /// </summary>
        /// <typeparam name="TParent"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <typeparam name="TTargetProperty"></typeparam>
        /// <param name="token"></param>
        /// <param name="propertySelector"></param>
        /// <returns></returns>
        public static FluentToken <TParent, TTargetProperty> Or <TParent, TProperty, TTargetProperty>(
            this FluentToken <TParent, TTargetProperty> token, Expression <Func <TParent, TProperty> > propertySelector)
        {
            token.PropertyNames.Add(ExpressionTreeHelper.PropertyName(propertySelector));

            return(token);
        }
        /// <summary>
        ///     Second part of the rule declaration; specifies the function that will compute the value of the target property
        /// </summary>
        /// <typeparam name="TParent"></typeparam>
        /// <typeparam name="TTargetProperty"></typeparam>
        /// <param name="token"></param>
        /// <param name="valueComputer"></param>
        /// <param name="manualExplain">optionally provide a human readable description</param>
        /// <returns></returns>
        public static FluentToken <TParent, TTargetProperty> With <TParent, TTargetProperty>(
            this FluentToken <TParent, TTargetProperty> token, Expression <Func <TParent, TTargetProperty> > valueComputer, string manualExplain = null)
        {
            token.ValueComputerExplained = manualExplain ?? valueComputer.TryExplain();
            token.ValueComputer          = valueComputer.Compile();

            return(token);
        }
        /// <summary>
        ///     Specifies an optional applicability condition as a predicate; if false the rule will not be triggered
        /// </summary>
        /// <typeparam name="TParent"></typeparam>
        /// <typeparam name="TTargetProperty"></typeparam>
        /// <param name="token"></param>
        /// <param name="ifPredicate"></param>
        /// <param name="manualExplain">optionally provide a human readable description</param>
        /// <returns></returns>
        public static FluentToken <TParent, TTargetProperty> If <TParent, TTargetProperty>(
            this FluentToken <TParent, TTargetProperty> token, Expression <Func <TParent, bool> > ifPredicate, string manualExplain = null)
        {
            token.IfPredicate = ifPredicate.Compile();
            token.IfExplained = manualExplain ?? ifPredicate.TryExplain();

            return(token);
        }
        /// <summary>
        ///     Specifies the first trigger property
        /// </summary>
        /// <typeparam name="TParent"></typeparam>
        /// <typeparam name="TTargetProperty"></typeparam>
        /// <param name="token"></param>
        /// <param name="propertySelectors"></param>
        /// <returns></returns>
        public static void OnChanged <TParent, TTargetProperty>(
            this FluentToken <TParent, TTargetProperty> token, params Expression <Func <TParent, object> >[] propertySelectors)
        {
            foreach (var propertySelector in propertySelectors)
            {
                token.PropertyNames.Add(ExpressionTreeHelper.PropertyName(propertySelector));
            }

            var propertyName = ExpressionTreeHelper.PropertyName(token.TargetPropertySelector);

            bool Updater(TParent parent)
            {
                if (token.IfPredicate != null)
                {
                    if (!token.IfPredicate(parent))
                    {
                        return(false);
                    }
                }

                var newValue = token.ValueComputer(parent);

                var oldValue = RuntimeCompiler <TParent, TTargetProperty> .Getter(token.TargetPropertySelector)(parent);

                if (Equals(oldValue, newValue))
                {
                    return(false);
                }

                RuntimeCompiler <TParent, TTargetProperty> .SetterFromGetter(token.TargetPropertySelector)(parent,
                                                                                                           newValue);

                return(true);
            }

            var rule = new Rule <TParent>
            {
                TriggerProperties      = token.PropertyNames,
                Updater                = Updater,
                TargetPropertyName     = propertyName,
                IfExplained            = token.IfExplained,
                ValueComputerExplained = token.ValueComputerExplained
            };


            token.MappingRulesContainer.Rules.Add(rule);

            foreach (var name in token.PropertyNames)
            {
                if (!token.MappingRulesContainer.RulesByTrigger.TryGetValue(name, out var rules))
                {
                    rules = new List <Rule <TParent> >();
                    token.MappingRulesContainer.RulesByTrigger.Add(name, rules);
                }

                rules.Add(rule);
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        ///     Always the last NON OPTIONAL statement in a rule declaration
        ///     Internally produces an instance of <see cref="Rule{TParent}" /> and adds it into the rules engine
        /// </summary>
        /// <typeparam name="TParent"></typeparam>
        /// <typeparam name="TTargetProperty"></typeparam>
        /// <param name="token"></param>
        public static void EndRule <TParent, TTargetProperty>(this FluentToken <TParent, TTargetProperty> token)
        {
            if (token.MappingRulesContainer == null)
            {
                throw new NotSupportedException("Error in fluent syntax. Start with a Set() statement");
            }

            var propertyName = ExpressionTreeHelper.PropertyName(token.TargetPropertySelector);

            bool Updater(TParent parent)
            {
                if (token.IfPredicate != null)
                {
                    if (!token.IfPredicate(parent))
                    {
                        return(false);
                    }
                }

                var newValue = token.ValueComputer(parent);

                var oldValue = RuntimeCompiler <TParent, TTargetProperty> .Getter(token.TargetPropertySelector)(parent);

                if (Equals(oldValue, newValue))
                {
                    return(false);
                }

                RuntimeCompiler <TParent, TTargetProperty> .SetterFromGetter(token.TargetPropertySelector)(parent,
                                                                                                           newValue);

                return(true);
            }

            var rule = new Rule <TParent>
            {
                TriggerProperties  = token.PropertyNames,
                Updater            = Updater,
                TargetPropertyName = propertyName
            };

            foreach (var name in token.PropertyNames)
            {
                if (!token.MappingRulesContainer.RulesByTrigger.TryGetValue(name, out var rules))
                {
                    rules = new List <Rule <TParent> >();
                    token.MappingRulesContainer.RulesByTrigger.Add(name, rules);
                }

                rules.Add(rule);
            }
        }