/// <summary> /// Creates a new context from a passed in Context Id /// </summary> /// <param name="contextId"></param> /// <param name="ruleExecuter"></param> /// <param name="ruleRepository"></param> /// <param name="ruleTemplateFactory"></param> /// <returns></returns> public static async Task <RuleContext <TFact, TOutput> > CreateContext( Guid contextId, IRuleExecuter <TFact, TOutput> ruleExecuter, IRuleRepository ruleRepository, IRuleTemplateFactory <TFact, TOutput> ruleTemplateFactory) { await ruleRepository.AddContext(contextId); return(new RuleContext <TFact, TOutput>(ruleExecuter, ruleRepository, contextId, ruleTemplateFactory)); }
private RuleContext( IRuleExecuter <TFact, TOutput> ruleExecuter, IRuleRepository ruleRepository, Guid contextId, IRuleTemplateFactory <TFact, TOutput> ruleTemplateFactory) { RuleExecuter = ruleExecuter; _ruleRepository = ruleRepository; ContextId = contextId; _ruleTemplateFactory = ruleTemplateFactory; }
/// <summary> /// Creates a new empty Context /// </summary> /// <param name="ruleExecuter"></param> /// <param name="ruleRepository"></param> /// <param name="ruleTemplateFactory">The injected abstract factory to create the rules</param> /// <returns></returns> public static async Task <RuleContext <TFact, TOutput> > CreateContext( IRuleExecuter <TFact, TOutput> ruleExecuter, IRuleRepository ruleRepository, IRuleTemplateFactory <TFact, TOutput> ruleTemplateFactory) { var newGuid = Guid.NewGuid(); return (await CreateContext(newGuid, ruleExecuter, ruleRepository, ruleTemplateFactory)); }
/// <summary> /// Loads a context by a given identifier based on a passed in repository /// </summary> /// <param name="identifier">Identifier representing a context</param> /// <param name="ruleExecuter">Passed in empty rule executer</param> /// <param name="ruleRepository">Repository for saved rules</param> /// <param name="ruleTemplateFactory">Factory for service specific templates</param> /// <returns></returns> public static async Task <RuleContext <TFact, TOutput> > LoadContext( Guid identifier, IRuleExecuter <TFact, TOutput> ruleExecuter, IRuleRepository ruleRepository, IRuleTemplateFactory <TFact, TOutput> ruleTemplateFactory) { var rules = await ruleRepository.GetRulesByContext(identifier); var context = new RuleContext <TFact, TOutput>(ruleExecuter, ruleRepository, identifier, ruleTemplateFactory); foreach (var ruleData in rules) { var condition = ruleTemplateFactory .CreateCondition(ruleData.ConditionType, ruleData.ConditionData); var consequence = ruleTemplateFactory .CreateConsequence(ruleData.ConsequenceType, ruleData.ConsequenceData); var template = new RuleTemplate <TFact, TOutput>(condition, consequence); ruleExecuter.AddRule(ruleData.Id, template.Rule); } return(context); }
/// <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; } }