public static IPropertyRuleBuilder<T, TProperty> IsNotNull<T, TProperty>( this IPropertyRuleBuilder<T, TProperty> ruleBuilder) where T : class where TProperty : class { return ruleBuilder.Must((_, property) => property != null); }
public static IPropertyRuleBuilder<T, TProperty> Count<T, TProperty>( this IPropertyRuleBuilder<T, TProperty> ruleBuilder, int count) where T : class where TProperty : IEnumerable { return ruleBuilder.Must((_, property) => property.Cast<object>().Count() == count); }
public static IPropertyRuleBuilder<T, TProperty> IsNotEmpty<T, TProperty>( this IPropertyRuleBuilder<T, TProperty> ruleBuilder) where T : class where TProperty : IEnumerable { return ruleBuilder.Must((_, property) => property.Cast<object>().Any()); }
public static IPropertyRuleBuilder<T, TProperty> Contains<T, TProperty, TElement>( this IPropertyRuleBuilder<T, TProperty> ruleBuilder, TElement element) where T : class where TProperty : IEnumerable<TElement> { return ruleBuilder.Must((_, property) => property.Contains(element)); }
/// <summary> /// Adds an <see cref="InlineConstraint{TProperty}"/> 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="TProperty">Type of property of the subject of the rule.</typeparam> /// <param name="propertyRuleBuilder"><see cref="IPropertyRuleBuilder{TContext,TSubject,TProperty}"/> currently configuring the rule.</param> /// <param name="minLength">Min Length property value can be.</param> /// <returns>A <see cref="IPropertyRuleBuilder{TContext,TSubject,TProperty}"/></returns> public static IPropertyRuleBuilder <TContext, TSubject, TProperty> MinLength <TContext, TSubject, TProperty> ( this IPropertyRuleBuilder <TContext, TSubject, TProperty> propertyRuleBuilder, int minLength) where TContext : RuleEngineContext <TSubject> { var message = Messages.Constraint_MinLength_Message.FormatCompareRuleEngineMessage(minLength, string.Empty); propertyRuleBuilder.Constrain(new InlineConstraint <TProperty> (lhs => lhs.ToString().Length >= minLength, message)); return(propertyRuleBuilder); }
public static IPropertyRuleBuilder<T, string> IsNotEqual<T>( this IPropertyRuleBuilder<T, string> ruleBuilder, string compareValue, StringComparison stringComparison) where T : class { return ruleBuilder.Must((_, property) => !(property == null && compareValue == null || property?.ToString().Equals(compareValue, stringComparison) == true)); }
/// <summary> /// Adds an <see cref="InlineConstraint{TProperty}"/> of GreaterThan 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="TProperty">Type of property of the subject of the rule.</typeparam> /// <param name="propertyRuleBuilder"><see cref="IPropertyRuleBuilder{TContext,TSubject,TProperty}"/> currently configuring the rule.</param> /// <param name="compareValue">Value to compare to value of property.</param> /// <returns>A <see cref="IPropertyRuleBuilder{TContext,TSubject,TProperty}"/></returns> public static IPropertyRuleBuilder <TContext, TSubject, TProperty> GreaterThan <TContext, TSubject, TProperty> ( this IPropertyRuleBuilder <TContext, TSubject, TProperty> propertyRuleBuilder, TProperty compareValue) where TContext : RuleEngineContext <TSubject> { var message = Messages.Constraints_Comparison_Message.FormatCompareRuleEngineMessage(compareValue, ">"); propertyRuleBuilder.Constrain(new InlineConstraint <TProperty>(lhs => Comparer <TProperty> .Default.Compare(compareValue, lhs) < 0, message)); return(propertyRuleBuilder); }
/// <summary> /// Adds an <see cref="ContextObjectInlineConstraint{TProperty}"/> 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="TProperty">Type of property of the subject of the rule.</typeparam> /// <param name="propertyRuleBuilder"><see cref="IPropertyRuleBuilder{TContext,TSubject,TProperty}"/> currently configuring the rule.</param> /// <param name="contextObjectName">Optional Name of ContextObject.</param> /// <returns>A <see cref="IPropertyRuleBuilder{TContext,TSubject,TProperty}"/></returns> public static IPropertyRuleBuilder <TContext, TSubject, TProperty> NotEqualToContextObject <TContext, TSubject, TProperty> ( this IPropertyRuleBuilder <TContext, TSubject, TProperty> propertyRuleBuilder, string contextObjectName = null) where TContext : RuleEngineContext <TSubject> { var message = Messages.Constraints_Comparison_Message.FormatCompareRuleEngineMessage("!="); propertyRuleBuilder.Constrain(new ContextObjectInlineConstraint <TProperty> ((lhs, ctx) => !ctx.Equals(lhs), message)); return(propertyRuleBuilder); }
/// <summary> /// Adds an <see cref="ContextObjectInlineConstraint{TProperty}"/> of LessThenOrEqualTo 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="TProperty">Type of property of the subject of the rule.</typeparam> /// <param name="propertyRuleBuilder"><see cref="IPropertyRuleBuilder{TContext,TSubject,TProperty}"/> currently configuring the rule.</param> /// <param name="contextObjectName">Optional Name of ContextObject.</param> /// <returns>A <see cref="IPropertyRuleBuilder{TContext,TSubject,TProperty}"/></returns> public static IPropertyRuleBuilder <TContext, TSubject, TProperty> LessThenOrEqualToContextObject <TContext, TSubject, TProperty> ( this IPropertyRuleBuilder <TContext, TSubject, TProperty> propertyRuleBuilder, string contextObjectName = null) where TContext : RuleEngineContext <TSubject> { var message = Messages.Constraints_Comparison_Message.FormatCompareRuleEngineMessage("<="); propertyRuleBuilder.Constrain(new ContextObjectInlineConstraint <TProperty>((lhs, ctx) => Comparer <TProperty> .Default.Compare(ctx, lhs) >= 0, message)); return(propertyRuleBuilder); }
public static IPropertyRuleBuilder<T, TProperty> IsEqual<T, TProperty>( this IPropertyRuleBuilder<T, TProperty> ruleBuilder, double compareValue) where T : class { var validationStep = new FloatEqualPropertyValidationStep<T, TProperty>(compareValue, 0.0001, true); ruleBuilder.AddValidationStep(validationStep); return ruleBuilder; }
public static IPropertyRuleBuilder<T, TProperty> IsNotEqual<T, TProperty>( this IPropertyRuleBuilder<T, TProperty> ruleBuilder, double compareValue, double comparisonTolerance) where T : class { var validationStep = new FloatEqualPropertyValidationStep<T, TProperty>(compareValue, comparisonTolerance, false); ruleBuilder.AddValidationStep(validationStep); return ruleBuilder; }
/// <summary> /// Adds an <see cref="InlineConstraint{TProperty}"/> to a rule. /// </summary> /// <typeparam name="TSubject">Type of subject of the rule.</typeparam> /// <typeparam name="TContext">Type of <see cref="IRuleEngineContext"/> of the rule.</typeparam> /// <typeparam name="TProperty">Type of property of the subject of the rule.</typeparam> /// <param name="propertyRuleBuilder"><see cref="IPropertyRuleBuilder{TContext,TSubject,TProperty}"/> currently configuring the rule.</param> /// <param name="ruleCollection">Rule Collection for property.</param> /// <param name="ruleSelector">Optional Rule Selector for <paramref name="ruleCollection"/></param> /// <returns>A <see cref="IPropertyRuleBuilder{TContext,TSubject,TProperty}"/>.</returns> public static IPropertyRuleBuilder <TContext, TSubject, TProperty> ConstrainWithCollection <TSubject, TContext, TProperty> ( this IPropertyRuleBuilder <TContext, TSubject, TProperty> propertyRuleBuilder, IRuleCollection <TProperty> ruleCollection, IRuleSelector ruleSelector = null) where TContext : RuleEngineContext <TSubject> { propertyRuleBuilder.Constrain(new RuleCollectionConstraint <TProperty> (ruleCollection, ruleSelector)); return(propertyRuleBuilder); }
public static IPropertyRuleBuilder<T, TProperty> HasLength<T, TProperty>( this IPropertyRuleBuilder<T, TProperty> ruleBuilder, Func<T, TProperty, int> checkLength) where T : class { var validationStep = new CheckLengthPropertyValidationStep<T, TProperty>(checkLength); ruleBuilder.AddValidationStep(validationStep); return ruleBuilder; }
/// <summary> /// Adds an <see cref="InlineConstraint{TProperty}"/> to a rule. /// </summary> /// <typeparam name="TSubject">Type of subject of the rule.</typeparam> /// <typeparam name="TContext">Type of <see cref="IRuleEngineContext"/> of the rule.</typeparam> /// <typeparam name="TProperty">Type of property of the subject of the rule.</typeparam> /// <param name="propertyRuleBuilder"><see cref="IPropertyRuleBuilder{TContext,TSubject,TProperty}"/> currently configuring the rule.</param> /// <param name="predicate"><see cref="Predicate{T}"/> to use in the inline constraint.</param> /// <param name="message">Rule Violation Message for Constraint.</param> /// <returns>A <see cref="IPropertyRuleBuilder{TContext,TSubject,TProperty}"/>.</returns> public static IPropertyRuleBuilder <TContext, TSubject, TProperty> Constrain <TSubject, TContext, TProperty> ( this IPropertyRuleBuilder <TContext, TSubject, TProperty> propertyRuleBuilder, Predicate <TProperty> predicate, string message = null) where TContext : RuleEngineContext <TSubject> { var inlineConstraint = new InlineConstraint <TProperty> (predicate, message); propertyRuleBuilder.Constrain(inlineConstraint); return(propertyRuleBuilder); }
public static IPropertyRuleBuilder<T, TProperty> EndsWith<T, TProperty>( this IPropertyRuleBuilder<T, TProperty> ruleBuilder, string text) where T : class { var validationStep = new EndsWithPropertyValidationStep<T, TProperty>(text); ruleBuilder.AddValidationStep(validationStep); return ruleBuilder; }
public static IPropertyRuleBuilder<T, TProperty> HasLength<T, TProperty>( this IPropertyRuleBuilder<T, TProperty> ruleBuilder, int minLength, int maxLength) where T : class { var validationStep = new HasLengthBetweenPropertyValidationStep<T, TProperty>(minLength, maxLength); ruleBuilder.AddValidationStep(validationStep); return ruleBuilder; }
public static IPropertyRuleBuilder<T, TProperty> Between<T, TProperty>( this IPropertyRuleBuilder<T, TProperty> ruleBuilder, TProperty lowerEnd, TProperty upperEnd) where T : class { var validationStep = new BetweenPropertyValidationStep<T, TProperty>(lowerEnd, upperEnd); ruleBuilder.AddValidationStep(validationStep); return ruleBuilder; }
public static IPropertyRuleBuilder<T, TProperty> HasMaximumLength<T, TProperty>( this IPropertyRuleBuilder<T, TProperty> ruleBuilder, int length) where T : class { var validationStep = new HasMaximumLengthPropertyValidationStep<T, TProperty>(length); ruleBuilder.AddValidationStep(validationStep); return ruleBuilder; }
public static IPropertyRuleBuilder<T, TProperty> IsNotEqual<T, TProperty>( this IPropertyRuleBuilder<T, TProperty> ruleBuilder, TProperty compareValue) where T : class { var validationStep = new EqualPropertyValidationStep<T, TProperty>(compareValue, false); ruleBuilder.AddValidationStep(validationStep); return ruleBuilder; }
public static IPropertyRuleBuilder<T, TProperty> Contains<T, TProperty>( this IPropertyRuleBuilder<T, TProperty> ruleBuilder, object element) where T : class where TProperty : IEnumerable { return ruleBuilder.Must((_, property) => property .Cast<object>() .Any(x => Comparer.Default.Compare(x, element) == 0)); }
/// <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="TProperty">Type of property of the subject of the rule.</typeparam> /// <param name="propertyRuleBuilder"><see cref="IPropertyRuleBuilder{TContext,TSubject,TProperty}"/> currently configuring the rule.</param> /// <returns>A <see cref="IPropertyRuleBuilder{TContext,TSubject,TProperty}"/></returns> public static IPropertyRuleBuilder <TContext, TSubject, TProperty> CannotBeFutureDate <TContext, TSubject, TProperty> ( this IPropertyRuleBuilder <TContext, TSubject, TProperty> propertyRuleBuilder) where TContext : RuleEngineContext <TSubject> where TProperty : IComparable <DateTime> { var compareValue = DateTime.Today.AddDays(1); var message = Messages.Constraints_Comparison_Message.FormatCompareRuleEngineMessage(compareValue, "<"); propertyRuleBuilder.Constrain(new InlineConstraint <TProperty>(lhs => lhs.CompareTo(compareValue) < 0, message)); return(propertyRuleBuilder); }
public static IPropertyRuleBuilder<T, TProperty> Must<T, TProperty>( this IPropertyRuleBuilder<T, TProperty> ruleBuilder, Func<T, TProperty, bool> validate) where T : class { Ensure.IsNotNull(validate, nameof(validate)); var validationStep = new ExtendedDelegatePropertyValidationStep<T, TProperty>(validate); ruleBuilder.AddValidationStep(validationStep); return ruleBuilder; }
/// <summary> /// Adds an <see cref="ContextObjectInlineConstraint{TProperty}"/> to a rule. /// </summary> /// <typeparam name="TSubject">Type of subject of the rule.</typeparam> /// <typeparam name="TContext">Type of <see cref="IRuleEngineContext"/> of the rule.</typeparam> /// <typeparam name="TProperty">Type of property of the subject of the rule.</typeparam> /// <param name="propertyRuleBuilder"><see cref="IPropertyRuleBuilder{TContext,TSubject,TProperty}"/> currently configuring the rule.</param> /// <param name="func"><see cref="Func{TProperty,TProperty,TResult}"/> to use in the context object inline constraint.</param> /// <param name="contextObjectName">Optional Name of the ContextObject.</param> /// <returns>A <see cref="IPropertyRuleBuilder{TContext,TSubject,TProperty}"/>.</returns> public static IPropertyRuleBuilder <TContext, TSubject, TProperty> ContextObjectConstrain <TSubject, TContext, TProperty> ( this IPropertyRuleBuilder <TContext, TSubject, TProperty> propertyRuleBuilder, Func <TProperty, TProperty, bool> func, string contextObjectName = null) where TContext : RuleEngineContext <TSubject> { var inlineConstraint = new ContextObjectInlineConstraint <TProperty> (func, contextObjectName); propertyRuleBuilder.Constrain(inlineConstraint); return(propertyRuleBuilder); }
public static IPropertyRuleBuilder<T, TProperty> IsFalse<T, TProperty>( this IPropertyRuleBuilder<T, TProperty> ruleBuilder, Func<TProperty, bool> isFalse) where T : class { Ensure.IsNotNull(isFalse, nameof(isFalse)); var validationStep = new DelegatePropertyValidationStep<T, TProperty>(property => !isFalse(property)); ruleBuilder.AddValidationStep(validationStep); return ruleBuilder; }
/// <summary> /// Adds an <see cref="InlineConstraint{TProperty}"/> of InList to the Rule. /// </summary> /// <typeparam name="TContext">The type of the context.</typeparam> /// <typeparam name="TSubject">The type of the subject.</typeparam> /// <typeparam name="TProperty">The type of the property.</typeparam> /// <param name="propertyRuleBuilder">The property rule builder.</param> /// <param name="list">The list to check.</param> /// <returns>A <see cref="IPropertyRuleBuilder{TContext,TSubject,TProperty}"/></returns> public static IPropertyRuleBuilder <TContext, TSubject, TProperty> InList <TContext, TSubject, TProperty>( this IPropertyRuleBuilder <TContext, TSubject, TProperty> propertyRuleBuilder, params TProperty[] list) where TContext : RuleEngineContext <TSubject> { Check.IsNotNull(list, "list is required."); var message = Messages.Constraints_InList_Message.FormatRuleEngineMessage(new Dictionary <string, string> { { "ListString", string.Join(", ", list) } }); propertyRuleBuilder.Constrain(new InlineConstraint <TProperty>(list.Contains, message)); return(propertyRuleBuilder); }
/// <summary> /// Adds an <see cref="InlineConstraint{TProperty}"/> 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="TProperty">Type of property of the subject of the rule.</typeparam> /// <param name="propertyRuleBuilder"><see cref="IPropertyRuleBuilder{TContext,TSubject,TProperty}"/> currently configuring the rule.</param> /// <param name="regexString">Regex string to check match on property value.</param> /// <returns>A <see cref="IPropertyRuleBuilder{TContext,TSubject,TProperty}"/></returns> public static IPropertyRuleBuilder <TContext, TSubject, TProperty> MatchesRegex <TContext, TSubject, TProperty> ( this IPropertyRuleBuilder <TContext, TSubject, TProperty> propertyRuleBuilder, string regexString) where TContext : RuleEngineContext <TSubject> { var message = Messages.Constraints_Regex_Message.FormatRuleEngineMessage(new Dictionary <string, string> { { "RegexString", regexString } }); propertyRuleBuilder.Constrain(new InlineConstraint <TProperty> (lhs => Regex.IsMatch(lhs.ToString(), regexString), message)); return(propertyRuleBuilder); }
/// <summary> /// Adds an <see cref="InlineConstraint{TProperty}"/> 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="TProperty">Type of property of the subject of the rule.</typeparam> /// <param name="propertyRuleBuilder"><see cref="IPropertyRuleBuilder{TContext,TSubject,TProperty}"/> 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="IPropertyRuleBuilder{TContext,TSubject,TProperty}"/></returns> public static IPropertyRuleBuilder <TContext, TSubject, TProperty> ExclusiveBetween <TContext, TSubject, TProperty> ( this IPropertyRuleBuilder <TContext, TSubject, TProperty> propertyRuleBuilder, TProperty startValue, TProperty endValue) where TContext : RuleEngineContext <TSubject> { var message = Messages.Constraints_ExclusiveBetween_Message.FormatRuleEngineMessage( new Dictionary <string, string> { { "StartValue", startValue.ToString() }, { "EndValue", startValue.ToString() } }); propertyRuleBuilder.Constrain( new InlineConstraint <TProperty>(lhs => Comparer <TProperty> .Default.Compare(startValue, lhs) < 0 && Comparer <TProperty> .Default.Compare(endValue, lhs) > 0, message)); return(propertyRuleBuilder); }
/// <summary> /// Adds an <see cref="InlineConstraint{TProperty}"/> 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="TProperty">Type of property of the subject of the rule.</typeparam> /// <param name="propertyRuleBuilder"><see cref="IPropertyRuleBuilder{TContext,TSubject,TProperty}"/> 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="IPropertyRuleBuilder{TContext,TSubject,TProperty}"/></returns> public static IPropertyRuleBuilder <TContext, TSubject, TProperty> MeetsSpecification <TContext, TSubject, TProperty> ( this IPropertyRuleBuilder <TContext, TSubject, TProperty> propertyRuleBuilder, ISpecification <TProperty> specification, string violationMessage = null) where TContext : RuleEngineContext <TSubject> { var message = violationMessage ?? Messages.Constraint_Specification_Message.FormatRuleEngineMessage( new Dictionary <string, string> { { "Specification", specification.ToString() } }); propertyRuleBuilder.Constrain(new InlineConstraint <TProperty> (specification.IsSatisfiedBy, message)); return(propertyRuleBuilder); }
/// <summary> /// Adds an <see cref="InlineConstraint{TProperty}"/> of InclusiveBetween 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="TProperty">Type of property of the subject of the rule.</typeparam> /// <param name="propertyRuleBuilder"><see cref="IPropertyRuleBuilder{TContext,TSubject,TProperty}"/> 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="IPropertyRuleBuilder{TContext,TSubject,TProperty}"/></returns> public static IPropertyRuleBuilder <TContext, TSubject, TProperty> InclusiveBetween <TContext, TSubject, TProperty> ( this IPropertyRuleBuilder <TContext, TSubject, TProperty> propertyRuleBuilder, IComparable startValue, IComparable endValue) where TContext : RuleEngineContext <TSubject> { var message = Messages.Constraints_InclusiveBetween_Message.FormatRuleEngineMessage( new Dictionary <string, string> { { "StartValue", startValue.ToString() }, { "EndValue", startValue.ToString() } }); propertyRuleBuilder.Constrain( new InlineConstraint <TProperty> (lhs => startValue.CompareTo(lhs) <= 0 && endValue.CompareTo(lhs) >= 0, message)); return(propertyRuleBuilder); }
/// <summary> /// Adds a Then clause to a Rule the Reports a <see cref="RuleViolation"/>. /// </summary> /// <typeparam name="TSubject">Type of subject of the rule.</typeparam> /// <typeparam name="TContext">Type of <see cref="IRuleEngineContext"/> of the rule.</typeparam> /// <typeparam name="TProperty">Type of property of the subject of the rule.</typeparam> /// <param name="propertyRuleBuilder"><see cref="IPropertyRuleBuilder{TContext,TSubject,TProperty}"/> currently configuring the rule.</param> /// <param name="message">Message to use in <see cref="RuleViolation"/></param> /// <param name="nameDictionary"><see cref="IDictionary{TKey,TValue}"/> to use when formating the <paramref name="message"/></param> /// <param name="propertyNames">Params of propertyNames that caused the rule violation.</param> /// <returns> /// A <see cref="IPropertyRuleBuilder{TContext,TSubject,TProperty}"/>. /// </returns> public static IPropertyRuleBuilder <TContext, TSubject, TProperty> ThenReportRuleViolation <TSubject, TContext, TProperty> ( this IPropertyRuleBuilder <TContext, TSubject, TProperty> propertyRuleBuilder, string message, IDictionary <string, string> nameDictionary = null, params string[] propertyNames) where TContext : RuleEngineContext <TSubject> { propertyRuleBuilder.Then( (s, ctx) => { var formattedMessage = message.FormatRuleEngineMessage( ctx.NameProvider.GetName( s, (Expression <Func <TSubject, TProperty> >)propertyRuleBuilder.PropertyRule.PropertyExpression), nameDictionary); ctx.RuleViolationReporter.Report( new RuleViolation(propertyRuleBuilder.PropertyRule, s, formattedMessage, propertyNames)); }); return(propertyRuleBuilder); }