Esempio n. 1
0
        /// <summary>
        /// Evaluates the rule check expression for a rule attribute (property or method attribute).
        /// The attributes of methods and properties need to be executed by reflection, so we need a
        /// public method for that purpose.
        /// </summary>
        /// <param name="ruleExecuter">The rule executer (inherits from <see cref="RuleExecuter{TData,TResultClass}"/>) that will invoke the rule validation.</param>
        /// <param name="ruleAttribute">The attribute that defines the rule.</param>
        /// <param name="propertyName">The name of the data to be validated by the rule.</param>
        /// <returns>A new instance of <see cref="RuleValidationResult"/>.</returns>
        public RuleValidationResult InvokeRuleExecutionForAttribute(IRuleExecuter ruleExecuter, ContractRuleBaseAttribute ruleAttribute, string propertyName)
        {
            if (ruleAttribute == null || ruleExecuter == null)
            {
                return(null);
            }

            var typeAttributeType = ruleAttribute.RuleType;

            if (typeAttributeType.Implements(typeof(IEnumerable)))
            {
                return(null);
            }

            // the following line would be more specific - but seems to be hard to be implemented
            ////if (!ruleAttribute.Type.Implements(typeof(RuleBase<,>)))
            if (!typeAttributeType.IsSubclassOf(typeof(RuleBaseInformation)))
            {
                throw new ArgumentException("The attribute does not contain a valid rule.");
            }

            var assertMethod = ruleExecuter.GetType().GetMethod("ExecuteRuleExpression");

            var parameter = ruleAttribute.Parameter;

            assertMethod =
                assertMethod.MakeGenericMethod(
                    parameter != null
                        ? parameter.GetType()
                        : typeof(object));

            try
            {
                // create an instance of the rule and invoke the Assert statement
                var constructorInfo = typeAttributeType.GetConstructor(Type.EmptyTypes);
                RuleBaseInformation rule;
                if (constructorInfo.ContainsGenericParameters)
                {
                    rule = CreateRule(typeAttributeType, ruleExecuter.GetValueType());
                }
                else
                {
                    rule = (RuleBaseInformation)constructorInfo.Invoke(null);
                }

                var ruleType = rule.GetType();
                if (!string.IsNullOrEmpty(ruleAttribute.Message))
                {
                    rule.Message = ruleAttribute.Message;
                }

                var invokeResult = (bool)assertMethod.Invoke(ruleExecuter, new[] { rule, parameter, propertyName });

                var result = new RuleValidationResult(
                    ruleType,
                    string.Format(
                        CultureInfo.CurrentCulture,
                        Resources.RuleValidationResultStandardMessage,
                        ruleType.Namespace + "." + ruleType.Name,
                        propertyName,
                        string.Format(CultureInfo.CurrentCulture, rule.Message, parameter, propertyName)),
                    propertyName,
                    invokeResult);

                return(result);
            }
            catch (TargetInvocationException ex)
            {
                throw ex.InnerException;
            }
        }