/// <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; } }