Defines methods to resolve parameter value from the context object.
        private RuleParameter CreateConditionParameter(
            Type containerType, RuleParameterValueResolver containerResolver, string prefix, PropertyInfo property, ParamAttribute paramAttr)
        {
            var propertyType       = property.PropertyType;
            var valueResolver      = new ChainedRuleParameterValueResolver().Chain(containerResolver, new PropertyBackedRuleParameterValueResolver(property));
            var supportedOperators = GetDefaultOperators(propertyType);
            IRuleParameterValueSource valueSource = null;

            if (paramAttr.ValueSource != null)
            {
                valueSource = TypeActivator.CreateInstance(paramAttr.ValueSource) as IRuleParameterValueSource;
            }
            else if (property.PropertyType.IsEnum)
            {
                propertyType = typeof(String);
                valueSource  = StaticRuleParameterValueSource.FromEnum(property.PropertyType);
            }
            else if (IsNullableEnum(property.PropertyType))
            {
                propertyType = typeof(String);
                valueSource  = StaticRuleParameterValueSource.FromEnum(Nullable.GetUnderlyingType(property.PropertyType));
            }

            var paramName = prefix + (paramAttr.Name ?? property.Name);

            return(new RuleParameter(paramName, propertyType, valueResolver, supportedOperators)
            {
                ValueSource = valueSource
            });
        }
        private RuleParameter CreateConditionParameter(
            Type containerType, RuleParameterValueResolver containerResolver, string prefix, PropertyInfo property, ParamAttribute paramAttr)
        {
            var propertyType = property.PropertyType;
            var valueResolver = new ChainedRuleParameterValueResolver().Chain(containerResolver, new PropertyBackedRuleParameterValueResolver(property));
            var supportedOperators = GetDefaultOperators(propertyType);
            IRuleParameterValueSource valueSource = null;

            if (paramAttr.ValueSource != null)
            {
                valueSource = TypeActivator.CreateInstance(paramAttr.ValueSource) as IRuleParameterValueSource;
            }
            else if (property.PropertyType.IsEnum)
            {
                propertyType = typeof(String);
                valueSource = StaticRuleParameterValueSource.FromEnum(property.PropertyType);
            }
            else if (IsNullableEnum(property.PropertyType))
            {
                propertyType = typeof(String);
                valueSource = StaticRuleParameterValueSource.FromEnum(Nullable.GetUnderlyingType(property.PropertyType));
            }

            var paramName = prefix + (paramAttr.Name ?? property.Name);

            return new RuleParameter(paramName, propertyType, valueResolver, supportedOperators)
            {
                ValueSource = valueSource
            };
        }
Example #3
0
        public RuleParameter(string name, Type valueType, RuleParameterValueResolver valueResolver, IEnumerable<IComparisonOperator> supportedOperators)
        {
            Require.NotNullOrEmpty(name, "name");
            Require.NotNull(valueType, "valueType");
            Require.NotNull(valueResolver, "valueResolver");
            Require.NotNull(supportedOperators, "supportedOperators");

            Name = name;
            ValueType = valueType;
            ValueResolver = valueResolver;
            SupportedOperators = supportedOperators.ToList();
        }
Example #4
0
        public RuleParameter(string name, Type valueType, RuleParameterValueResolver valueResolver, IEnumerable <IComparisonOperator> supportedOperators)
        {
            Require.NotNullOrEmpty(name, "name");
            Require.NotNull(valueType, "valueType");
            Require.NotNull(valueResolver, "valueResolver");
            Require.NotNull(supportedOperators, "supportedOperators");

            Name               = name;
            ValueType          = valueType;
            ValueResolver      = valueResolver;
            SupportedOperators = supportedOperators.ToList();
        }
        /// <summary>
        /// Gets the available parameters for the specified data context type,
        /// with a specific data context adapter to adapt original data context to the final data context to which the parameters is applicable.
        /// </summary>
        /// <param name="dataContextType">The data context type.</param>
        /// <param name="dataContextAdapter">The adapter to adapt original data context to the final data context.</param>
        /// <returns>Available parameters.</returns>
        public IEnumerable <RuleParameter> GetParameters(Type dataContextType, Func <object, object> dataContextAdapter)
        {
            Require.NotNull(dataContextType, "dataContextType");

            var containerResolver = RuleParameterValueResolver.Dumb();

            if (dataContextAdapter != null)
            {
                Func <RuleParameter, object, object> resolver = (param, dataContext) => dataContextAdapter(dataContext);
                containerResolver = RuleParameterValueResolver.FromDelegate(resolver);
            }

            return(FindConditionParameters(dataContextType, containerResolver, null));
        }
 public ChainedRuleParameterValueResolver Chain(RuleParameterValueResolver resolver)
 {
     _resolvers.Add(resolver);
     return this;
 }
 public ChainedRuleParameterValueResolver Chain(RuleParameterValueResolver resolver)
 {
     _resolvers.Add(resolver);
     return(this);
 }
        private List <RuleParameter> FindConditionParameters(Type containerType, RuleParameterValueResolver containerResolver, string prefix)
        {
            var parameters = new List <RuleParameter>();

            foreach (var property in containerType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
            {
                var refAttr = property.GetCustomAttribute <ReferenceAttribute>(false);
                if (refAttr != null)
                {
                    var resolver = new ChainedRuleParameterValueResolver().Chain(containerResolver, new PropertyBackedRuleParameterValueResolver(property));

                    var referencingType = refAttr.ReferencingType ?? property.PropertyType;
                    // Indirect reference
                    if (referencingType != property.PropertyType)
                    {
                        if (refAttr.ReferenceResolver == null)
                        {
                            throw new InvalidOperationException("Indirect reference must speicify a reference resolver. Property: " + property.ReflectedType.FullName + "." + property.Name + ".");
                        }

                        resolver.Chain(new IndirectReferenceAdapter(referencingType, refAttr.ReferenceResolver));
                    }

                    var newPrefix = prefix;

                    // refAttr.Prefix == null: Generate a default prefix
                    // refAttr.Prefix == String.Empty: Do not use prefix
                    // otherwise, use the specified prefix
                    if (refAttr.Prefix != null)
                    {
                        if (refAttr.Prefix.Length > 0)
                        {
                            newPrefix = prefix + (refAttr.Prefix.EndsWith(".") ? refAttr.Prefix : refAttr.Prefix + ".");
                        }
                    }
                    else
                    {
                        // Try to get a smart default preifx if developer doesn't specify one.
                        // If the property name is like BrandId,
                        // then we use 'Brand' instead of 'BrandId'.
                        // So when we are investigating Brand.Name property, we can get a better parameter name 'BrandName' instead of 'BrandIdName'
                        if (property.Name.EndsWith("Id"))
                        {
                            newPrefix = prefix + property.Name.Substring(0, property.Name.Length - 2);
                        }
                        else
                        {
                            newPrefix = prefix + property.Name;
                        }

                        newPrefix = newPrefix + ".";
                    }

                    parameters.AddRange(FindConditionParameters(referencingType, resolver, newPrefix));

                    // Add also extended parameters
                    foreach (var provider in Providers)
                    {
                        if (provider.GetType() != typeof(DefaultRuleParameterProvider))
                        {
                            var additionalParams = provider.GetParameters(referencingType);
                            foreach (var param in additionalParams)
                            {
                                var valueResolver = new ChainedRuleParameterValueResolver();
                                valueResolver.Chain(resolver);
                                valueResolver.Chain(param.ValueResolver);

                                var adaptedParam = new RuleParameter(newPrefix + param.Name, param.ValueType, valueResolver, param.SupportedOperators)
                                {
                                    ValueSource = param.ValueSource
                                };

                                parameters.Add(adaptedParam);
                            }
                        }
                    }
                }
                else
                {
                    var paramAttr = property.GetCustomAttribute <ParamAttribute>(false);
                    if (paramAttr != null)
                    {
                        parameters.Add(CreateConditionParameter(containerType, containerResolver, prefix, property, paramAttr));
                    }
                }
            }

            return(parameters);
        }
 public IEnumerable <RuleParameter> GetParameters(Type dataContextType)
 {
     Require.NotNull(dataContextType, "dataContextType");
     return(FindConditionParameters(dataContextType, RuleParameterValueResolver.Dumb(), null));
 }
        private List<RuleParameter> FindConditionParameters(Type containerType, RuleParameterValueResolver containerResolver, string prefix)
        {
            var parameters = new List<RuleParameter>();

            foreach (var property in containerType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
            {
                var refAttr = property.GetCustomAttribute<ReferenceAttribute>(false);
                if (refAttr != null)
                {
                    var resolver = new ChainedRuleParameterValueResolver().Chain(containerResolver, new PropertyBackedRuleParameterValueResolver(property));

                    var referencingType = refAttr.ReferencingType ?? property.PropertyType;
                    // Indirect reference
                    if (referencingType != property.PropertyType)
                    {
                        if (refAttr.ReferenceResolver == null)
                            throw new InvalidOperationException("Indirect reference must speicify a reference resolver. Property: " + property.ReflectedType.FullName + "." + property.Name + ".");

                        resolver.Chain(new IndirectReferenceAdapter(referencingType, refAttr.ReferenceResolver));
                    }

                    var newPrefix = prefix;

                    // refAttr.Prefix == null: Generate a default prefix
                    // refAttr.Prefix == String.Empty: Do not use prefix
                    // otherwise, use the specified prefix
                    if (refAttr.Prefix != null)
                    {
                        if (refAttr.Prefix.Length > 0)
                        {
                            newPrefix = prefix + (refAttr.Prefix.EndsWith(".") ? refAttr.Prefix : refAttr.Prefix + ".");
                        }
                    }
                    else
                    {
                        // Try to get a smart default preifx if developer doesn't specify one.
                        // If the property name is like BrandId,
                        // then we use 'Brand' instead of 'BrandId'.
                        // So when we are investigating Brand.Name property, we can get a better parameter name 'BrandName' instead of 'BrandIdName'
                        if (property.Name.EndsWith("Id"))
                        {
                            newPrefix = prefix + property.Name.Substring(0, property.Name.Length - 2);
                        }
                        else
                        {
                            newPrefix = prefix + property.Name;
                        }

                        newPrefix = newPrefix + ".";
                    }

                    parameters.AddRange(FindConditionParameters(referencingType, resolver, newPrefix));

                    // Add also extended parameters
                    foreach (var provider in Providers)
                    {
                        if (provider.GetType() != typeof(DefaultRuleParameterProvider))
                        {
                            var additionalParams = provider.GetParameters(referencingType);
                            foreach (var param in additionalParams)
                            {
                                var valueResolver = new ChainedRuleParameterValueResolver();
                                valueResolver.Chain(resolver);
                                valueResolver.Chain(param.ValueResolver);

                                var adaptedParam = new RuleParameter(newPrefix + param.Name, param.ValueType, valueResolver, param.SupportedOperators)
                                {
                                    ValueSource = param.ValueSource
                                };

                                parameters.Add(adaptedParam);
                            }
                        }
                    }
                }
                else
                {
                    var paramAttr = property.GetCustomAttribute<ParamAttribute>(false);
                    if (paramAttr != null)
                    {
                        parameters.Add(CreateConditionParameter(containerType, containerResolver, prefix, property, paramAttr));
                    }
                }
            }

            return parameters;
        }