/// <summary>Uses the subject for rule violation.</summary> /// <typeparam name="TContext">The type of the context.</typeparam> /// <typeparam name="TSubject">The type of the subject.</typeparam> /// <typeparam name="TContextObject">The type of the context object.</typeparam> /// <param name="ruleBuilder">The rule builder.</param> /// <param name="propertyExpression">The property expression.</param> /// <returns>A Context Object Provider Rule Builder.</returns> public static IContextObjectProviderRuleBuilder <TContext, TSubject, TContextObject> UseSubjectForRuleViolation <TContext, TSubject, TContextObject> ( this IContextObjectProviderRuleBuilder <TContext, TSubject, TContextObject> ruleBuilder, Expression <Func <TSubject, object> > propertyExpression) where TContext : RuleEngineContext <TSubject> { ruleBuilder.ElseThen( (s, ctx) => { var failedConstraints = ctx.WorkingMemory.GetContextObject <List <IConstraint> > (ruleBuilder.Rule.Name); foreach (var constraint in failedConstraints) { if (!(constraint is IHandleAddingRuleViolations)) { var propertyName = ctx.NameProvider.GetName(s, propertyExpression); var formatedMessage = constraint.Message.FormatRuleEngineMessage(propertyName); var ruleViolation = new RuleViolation( ruleBuilder.Rule, s, formatedMessage, PropertyUtil.ExtractPropertyName(propertyExpression)); ctx.RuleViolationReporter.Report(ruleViolation); } } failedConstraints.Clear(); }); return(ruleBuilder); }
/// <summary> /// Adds an <see cref="InlineConstraint{TContextObject}"/> to the Rule. /// </summary> /// <typeparam name="TContext">The type of the context.</typeparam> /// <typeparam name="TSubject">The type of the subject.</typeparam> /// <typeparam name="TContextObject">The type of the context object.</typeparam> /// <param name="ruleBuilder">The rule builder.</param> /// <param name="predicate">The predicate.</param> /// <param name="message">The message.</param> /// <returns>A <see cref="IContextObjectProviderRuleBuilder{TContext,TSubject,TContextObject}"/></returns> public static IContextObjectProviderRuleBuilder <TContext, TSubject, TContextObject> Constrain <TContext, TSubject, TContextObject> ( this IContextObjectProviderRuleBuilder <TContext, TSubject, TContextObject> ruleBuilder, Predicate <object> predicate, string message) where TContext : RuleEngineContext <TSubject> { ruleBuilder.Constrain(new InlineConstraint <object> (predicate, message)); return(ruleBuilder); }
/// <summary> /// Adds a WhenClause to the rule checking for duplicates, and Adds A ThenCluase that will report the violation if it occurs. /// </summary> /// <typeparam name="TContext">The type of the context.</typeparam> /// <typeparam name="TSubject">The type of the subject.</typeparam> /// <typeparam name="TContextObject">The type of the context object.</typeparam> /// <param name="ruleBuilder">The rule builder.</param> /// <param name="collectionFunc">The collection func.</param> /// <returns>A <see cref="IRuleBuilder{TContext,TSubject}"/></returns> public static IRuleBuilder <TContext, TSubject> NoDuplicates <TContext, TSubject, TContextObject> ( this IContextObjectProviderRuleBuilder <TContext, TSubject, TContextObject> ruleBuilder, Func <TContext, IEnumerable <TContextObject> > collectionFunc) where TContext : RuleEngineContext <TSubject> { if (ruleBuilder.Constraints.Count() > 0) { throw new InvalidRuleException("Cannot use NoDuplicates after a constraint has already been added to the Rule."); } return(ruleBuilder.When( (s, ctx) => { var collection = collectionFunc(ctx); var contextObject = ruleBuilder.GetContextObject(ctx.WorkingMemory); bool isDuplicate; if (contextObject is IValuesEquatable) { var aggregateNodeValueObject = (contextObject as IValuesEquatable); isDuplicate = collection.Any(item => aggregateNodeValueObject.ValuesEqual(item)); } else { isDuplicate = collection.Any(item => item.Equals(contextObject)); } return isDuplicate; }) .ThenReportRuleViolation( (s, ctx) => string.Format( "Cannot have duplicate {0}.", ctx.NameProvider.GetName(ruleBuilder.GetContextObject(ctx.WorkingMemory))))); }
/// <summary> /// Adds an <see cref="InlineConstraint{TProperty}"/> of GreaterThan todays date to the Rule. /// </summary> /// <typeparam name="TContext">Type of <see cref="IRuleEngineContext"/> of the rule.</typeparam> /// <typeparam name="TSubject">Type of subject of the rule.</typeparam> /// <typeparam name="TContextObject">Type of property of the subject of the rule.</typeparam> /// <param name="ruleBuilder"><see cref="IContextObjectProviderRuleBuilder{TContext,TSubject,TContextObject}"/> currently configuring the rule.</param> /// <returns>A <see cref="IContextObjectProviderRuleBuilder{TContext,TSubject,TContextObject}"/></returns> public static IContextObjectProviderRuleBuilder <TContext, TSubject, TContextObject> CannotBeFutureDate <TContext, TSubject, TContextObject> ( this IContextObjectProviderRuleBuilder <TContext, TSubject, TContextObject> ruleBuilder) where TContext : RuleEngineContext <TSubject> { ruleBuilder.GreaterThan(DateTime.Today); return(ruleBuilder); }
/// <summary> /// Adds an <see cref="InlineConstraint{TContextObject}"/> of MinLength to the Rule. /// </summary> /// <typeparam name="TContext">Type of <see cref="IRuleEngineContext"/> of the rule.</typeparam> /// <typeparam name="TSubject">Type of subject of the rule.</typeparam> /// <typeparam name="TContextObject">Type of property of the subject of the rule.</typeparam> /// <param name="ruleBuilder"><see cref="IContextObjectProviderRuleBuilder{TContext,TSubject,TContextObject}"/> currently configuring the rule.</param> /// <param name="minLength">Min Length property value can be.</param> /// <returns>A <see cref="IContextObjectProviderRuleBuilder{TContext,TSubject,TContextObject}"/></returns> public static IContextObjectProviderRuleBuilder <TContext, TSubject, TContextObject> MinLength <TContext, TSubject, TContextObject> ( this IContextObjectProviderRuleBuilder <TContext, TSubject, TContextObject> ruleBuilder, int minLength) where TContext : RuleEngineContext <TSubject> { var message = Messages.Constraint_MinLength_Message.FormatCompareRuleEngineMessage(minLength, string.Empty); ruleBuilder.Constrain(new InlineConstraint <object> (lhs => lhs.ToString().Length >= minLength, message)); return(ruleBuilder); }
/// <summary> /// Adds a WhenClause to the rule that checks the context object against a rule collection that returns true if a rule violation occurs from rule collection. /// </summary> /// <typeparam name="TContext">The type of the context.</typeparam> /// <typeparam name="TSubject">The type of the subject.</typeparam> /// <typeparam name="TContextObject">The type of the context object.</typeparam> /// <param name="ruleBuilder">The rule builder.</param> /// <param name="ruleCollection">The rule collection.</param> /// <param name="ruleSelector">The rule selector.</param> /// <returns> /// A <see cref="IRuleBuilder{TContext,TSubject}"/> /// </returns> public static IRuleBuilder <TContext, TSubject> WithCollection <TContext, TSubject, TContextObject> ( this IContextObjectProviderRuleBuilder <TContext, TSubject, TContextObject> ruleBuilder, IRuleCollection <TContextObject> ruleCollection, IRuleSelector ruleSelector = null) where TContext : RuleEngineContext <TSubject> { ruleBuilder.Constrain(new RuleCollectionConstraint <TContextObject> (ruleCollection, ruleSelector)); return(ruleBuilder); }
/// <summary> /// Adds an <see cref="InlineConstraint{TContextObject}"/> of NotEqualTo to the Rule. /// </summary> /// <typeparam name="TContext">Type of <see cref="IRuleEngineContext"/> of the rule.</typeparam> /// <typeparam name="TSubject">Type of subject of the rule.</typeparam> /// <typeparam name="TContextObject">Type of property of the subject of the rule.</typeparam> /// <param name="ruleBuilder"><see cref="IContextObjectProviderRuleBuilder{TContext,TSubject,TContextObject}"/> currently configuring the rule.</param> /// <param name="compareValue">Value to compare to value of property.</param> /// <returns>A <see cref="IContextObjectProviderRuleBuilder{TContext,TSubject,TContextObject}"/></returns> public static IContextObjectProviderRuleBuilder <TContext, TSubject, TContextObject> NotEqualTo <TContext, TSubject, TContextObject> ( this IContextObjectProviderRuleBuilder <TContext, TSubject, TContextObject> ruleBuilder, IComparable compareValue) where TContext : RuleEngineContext <TSubject> { var message = Messages.Constraints_Comparison_Message.FormatCompareRuleEngineMessage(compareValue, "!="); ruleBuilder.Constrain(new InlineConstraint <object> (lhs => compareValue.CompareTo(lhs) != 0, message)); return(ruleBuilder); }
/// <summary> /// Adds a propertyExpression to the Context Object in the Rule Builder. /// </summary> /// <typeparam name="TContext">The type of the context.</typeparam> /// <typeparam name="TSubject">The type of the subject.</typeparam> /// <typeparam name="TContextObject">The type of the context object.</typeparam> /// <param name="ruleBuilder">The rule builder.</param> /// <param name="propertyExpression">The property expression.</param> /// <returns>A <see cref="IContextObjectProviderRuleBuilder{TContext,TSubject,TContextObject}"/></returns> public static IContextObjectProviderRuleBuilder <TContext, TSubject, TContextObject> WithProperty <TContext, TSubject, TContextObject> ( this IContextObjectProviderRuleBuilder <TContext, TSubject, TContextObject> ruleBuilder, Expression <Func <TContextObject, object> > propertyExpression) where TContext : RuleEngineContext <TSubject> { return(new ContextObjectProviderRuleBuilder <TContext, TSubject, TContextObject> ( ruleBuilder.Rule as Rule, ruleBuilder.ContextObjectName, propertyExpression)); }
/// <summary> /// Adds an <see cref="InlineConstraint{TContextObject}"/> of Regex Match to the Rule. /// </summary> /// <typeparam name="TContext">Type of <see cref="IRuleEngineContext"/> of the rule.</typeparam> /// <typeparam name="TSubject">Type of subject of the rule.</typeparam> /// <typeparam name="TContextObject">Type of property of the subject of the rule.</typeparam> /// <param name="ruleBuilder"><see cref="IContextObjectProviderRuleBuilder{TContext,TSubject,TContextObject}"/> currently configuring the rule.</param> /// <param name="regexString">Regex string to check match on property value.</param> /// <returns>A <see cref="IContextObjectProviderRuleBuilder{TContext,TSubject,TContextObject}"/></returns> public static IContextObjectProviderRuleBuilder <TContext, TSubject, TContextObject> MatchesRegex <TContext, TSubject, TContextObject> ( this IContextObjectProviderRuleBuilder <TContext, TSubject, TContextObject> ruleBuilder, string regexString) where TContext : RuleEngineContext <TSubject> { var message = Messages.Constraints_Regex_Message.FormatRuleEngineMessage(new Dictionary <string, string> { { "RegexString", regexString } }); ruleBuilder.Constrain(new InlineConstraint <object> (lhs => Regex.IsMatch(lhs.ToString(), regexString), message)); return(ruleBuilder); }
/// <summary> /// Adds an <see cref="InlineConstraint{TContextObject}"/> of Specification to the Rule. /// </summary> /// <typeparam name="TContext">Type of <see cref="IRuleEngineContext"/> of the rule.</typeparam> /// <typeparam name="TSubject">Type of subject of the rule.</typeparam> /// <typeparam name="TContextObject">Type of property of the subject of the rule.</typeparam> /// <param name="ruleBuilder"><see cref="IContextObjectProviderRuleBuilder{TContext,TSubject,TContextObject}"/> currently configuring the rule.</param> /// <param name="specification"><see cref="ISpecification{TEntity}"/> to use in Constraint.</param> /// <param name="violationMessage">Violation message to use in Constraint.</param> /// <returns>A <see cref="IContextObjectProviderRuleBuilder{TContext,TSubject,TContextObject}"/></returns> public static IContextObjectProviderRuleBuilder <TContext, TSubject, TContextObject> MeetsSpecification <TContext, TSubject, TContextObject> ( this IContextObjectProviderRuleBuilder <TContext, TSubject, TContextObject> ruleBuilder, ISpecification <object> specification, string violationMessage = null) where TContext : RuleEngineContext <TSubject> { var message = violationMessage ?? Messages.Constraint_Specification_Message.FormatRuleEngineMessage( new Dictionary <string, string> { { "Specification", specification.ToString() } }); ruleBuilder.Constrain(new InlineConstraint <object> (specification.IsSatisfiedBy, message)); return(ruleBuilder); }
/// <summary> /// Adds an <see cref="InlineConstraint{TContextObject}"/> of ExclusiveBetween to the Rule. /// </summary> /// <typeparam name="TContext">Type of <see cref="IRuleEngineContext"/> of the rule.</typeparam> /// <typeparam name="TSubject">Type of subject of the rule.</typeparam> /// <typeparam name="TContextObject">Type of property of the subject of the rule.</typeparam> /// <param name="ruleBuilder"><see cref="IContextObjectProviderRuleBuilder{TContext,TSubject,TContextObject}"/> currently configuring the rule.</param> /// <param name="startValue">Start Value to use in comparison to property value.</param> /// <param name="endValue">End Value to use in comparison to property value.</param> /// <returns>A <see cref="IContextObjectProviderRuleBuilder{TContext,TSubject,TContextObject}"/></returns> public static IContextObjectProviderRuleBuilder <TContext, TSubject, TContextObject> ExclusiveBetween <TContext, TSubject, TContextObject> ( this IContextObjectProviderRuleBuilder <TContext, TSubject, TContextObject> ruleBuilder, IComparable startValue, IComparable endValue) where TContext : RuleEngineContext <TSubject> { var message = Messages.Constraints_ExclusiveBetween_Message.FormatRuleEngineMessage( new Dictionary <string, string> { { "StartValue", startValue.ToString() }, { "EndValue", startValue.ToString() } }); ruleBuilder.Constrain( new InlineConstraint <object> (lhs => startValue.CompareTo(lhs) < 0 && endValue.CompareTo(lhs) > 0, message)); return(ruleBuilder); }
/// <summary> /// Adds a <see cref="NotEmptyConstraint"/> to the Rule. /// </summary> /// <typeparam name="TContext">Type of <see cref="IRuleEngineContext"/> of the rule.</typeparam> /// <typeparam name="TSubject">Type of subject of the rule.</typeparam> /// <typeparam name="TContextObject">Type of property of the subject of the rule.</typeparam> /// <param name="ruleBuilder"><see cref="IContextObjectProviderRuleBuilder{TContext,TSubject,TContextObject}"/> currently configuring the rule.</param> /// <returns>A <see cref="IContextObjectProviderRuleBuilder{TContext,TSubject,TContextObject}"/></returns> public static IContextObjectProviderRuleBuilder <TContext, TSubject, TContextObject> NotEmpty <TContext, TSubject, TContextObject> ( this IContextObjectProviderRuleBuilder <TContext, TSubject, TContextObject> ruleBuilder) where TContext : RuleEngineContext <TSubject> { ruleBuilder.Constrain(new NotEmptyConstraint()); return(ruleBuilder); }