/// <summary> /// Defines a condition that applies to several rules /// </summary> /// <param name="predicate">The condition that should apply to multiple rules</param> /// <param name="action">Action that encapsulates the rules.</param> /// <returns></returns> public IConditionBuilder When(Func <T, bool> predicate, Action action) { var propertyRules = new List <IValidationRule>(); using (_rules.OnItemAdded(propertyRules.Add)) { action(); } // Generate unique ID for this shared condition. var id = "_FV_Condition_" + Guid.NewGuid(); bool Condition(ValidationContext context) { string cacheId = null; if (context.InstanceToValidate != null) { cacheId = id + context.InstanceToValidate.GetHashCode(); if (context.RootContextData.TryGetValue(cacheId, out var value)) { if (value is bool result) { return(result); } } } var executionResult = predicate((T)context.InstanceToValidate); if (context.InstanceToValidate != null) { context.RootContextData[cacheId] = executionResult; } return(executionResult); } // Must apply the predicate after the rule has been fully created to ensure any rules-specific conditions have already been applied. foreach (var rule in propertyRules) { //TODO for FV 9 remove explicit reference to CollectionPropertyRule. if (rule is PropertyRule p) { p.ApplySharedCondition(Condition); } else { throw new NotSupportedException("Cannot call the root-level When/Unless methods on rules that don't inherit from PropertyRule"); } } return(new ConditionOtherwiseBuilder(_rules, Condition)); }
/// <summary> /// Defines a condition that applies to several rules /// </summary> /// <param name="predicate">The condition that should apply to multiple rules</param> /// <param name="action">Action that encapsulates the rules.</param> /// <returns></returns> public IConditionBuilder When(Func <T, ValidationContext <T>, bool> predicate, Action action) { var propertyRules = new List <IValidationRuleInternal <T> >(); using (_rules.OnItemAdded(propertyRules.Add)) { action(); } // Generate unique ID for this shared condition. var id = "_FV_Condition_" + Guid.NewGuid(); bool Condition(IValidationContext context) { var actualContext = ValidationContext <T> .GetFromNonGenericContext(context); if (actualContext.InstanceToValidate != null) { if (actualContext.SharedConditionCache.TryGetValue(id, out var cachedResults)) { if (cachedResults.TryGetValue(actualContext.InstanceToValidate, out bool result)) { return(result); } } } var executionResult = predicate(actualContext.InstanceToValidate, actualContext); if (actualContext.InstanceToValidate != null) { if (actualContext.SharedConditionCache.TryGetValue(id, out var cachedResults)) { cachedResults.Add(actualContext.InstanceToValidate, executionResult); } else { actualContext.SharedConditionCache.Add(id, new Dictionary <T, bool> { { actualContext.InstanceToValidate, executionResult } }); } } return(executionResult); } // Must apply the predicate after the rule has been fully created to ensure any rules-specific conditions have already been applied. foreach (var rule in propertyRules) { rule.ApplySharedCondition(Condition); } return(new ConditionOtherwiseBuilder <T>(_rules, Condition)); }
/// <summary> /// Defines an asynchronous condition that applies to several rules /// </summary> /// <param name="predicate">The asynchronous condition that should apply to multiple rules</param> /// <param name="action">Action that encapsulates the rules.</param> /// <returns></returns> public IConditionBuilder WhenAsync(Func <T, CancellationToken, Task <bool> > predicate, Action action) { var propertyRules = new List <IValidationRule>(); using (_rules.OnItemAdded(propertyRules.Add)) { action(); } // Generate unique ID for this shared condition. var id = "_FV_AsyncCondition_" + Guid.NewGuid(); async Task <bool> Condition(ValidationContext context, CancellationToken ct) { string cacheId = null; if (context.InstanceToValidate != null) { cacheId = id + context.InstanceToValidate.GetHashCode(); if (context.RootContextData.TryGetValue(cacheId, out var value)) { if (value is bool result) { return(result); } } } var executionResult = await predicate((T)context.InstanceToValidate, ct); if (context.InstanceToValidate != null) { context.RootContextData[cacheId] = executionResult; } return(executionResult); } foreach (var rule in propertyRules) { //TODO for FV 9 remove explicit reference to CollectionPropertyRule. if (rule is PropertyRule p) { p.ApplySharedAsyncCondition(Condition); } else { throw new NotSupportedException("Cannot call the root-level When/Unless methods on rules that don't inherit from PropertyRule"); } } return(new AsyncConditionOtherwiseBuilder(_rules, Condition)); }
/// <summary> /// Defines an asynchronous condition that applies to several rules /// </summary> /// <param name="predicate">The asynchronous condition that should apply to multiple rules</param> /// <param name="action">Action that encapsulates the rules.</param> /// <returns></returns> public IConditionBuilder WhenAsync(Func <T, ValidationContext <T>, CancellationToken, Task <bool> > predicate, Action action) { var propertyRules = new List <IValidationRuleInternal <T> >(); using (_rules.OnItemAdded(propertyRules.Add)) { action(); } // Generate unique ID for this shared condition. var id = "_FV_AsyncCondition_" + Guid.NewGuid(); async Task <bool> Condition(IValidationContext context, CancellationToken ct) { var actualContext = ValidationContext <T> .GetFromNonGenericContext(context); if (actualContext.InstanceToValidate != null) { if (actualContext.SharedConditionCache.TryGetValue(id, out var cachedResults)) { if (cachedResults.TryGetValue(actualContext.InstanceToValidate, out bool result)) { return(result); } } } var executionResult = await predicate((T)context.InstanceToValidate, ValidationContext <T> .GetFromNonGenericContext(context), ct); if (actualContext.InstanceToValidate != null) { if (actualContext.SharedConditionCache.TryGetValue(id, out var cachedResults)) { cachedResults.Add(actualContext.InstanceToValidate, executionResult); } else { actualContext.SharedConditionCache.Add(id, new Dictionary <T, bool> { { actualContext.InstanceToValidate, executionResult } }); } } return(executionResult); } foreach (var rule in propertyRules) { rule.ApplySharedAsyncCondition(Condition); } return(new AsyncConditionOtherwiseBuilder <T>(_rules, Condition)); }
public virtual void Otherwise(Action action) { var propertyRules = new List <IValidationRule>(); Action <IValidationRule> onRuleAdded = propertyRules.Add; using (_rules.OnItemAdded(onRuleAdded)) { action(); } foreach (var rule in propertyRules) { rule.ApplySharedAsyncCondition(async(ctx, ct) => !await _condition(ctx, ct)); } }
public virtual void Otherwise(Action action) { var propertyRules = new List <IValidationRuleInternal <T> >(); Action <IValidationRuleInternal <T> > onRuleAdded = propertyRules.Add; using (_rules.OnItemAdded(onRuleAdded)) { action(); } foreach (var rule in propertyRules) { rule.ApplySharedCondition(ctx => !_condition(ctx)); } }
/// <summary> /// Defines a condition that applies to several rules /// </summary> /// <param name="predicate">The condition that should apply to multiple rules</param> /// <param name="action">Action that encapsulates the rules.</param> /// <returns></returns> public IConditionBuilder When(Func <T, ValidationContext <T>, bool> predicate, Action action) { var propertyRules = new List <IValidationRule>(); using (_rules.OnItemAdded(propertyRules.Add)) { action(); } // Generate unique ID for this shared condition. var id = "_FV_Condition_" + Guid.NewGuid(); bool Condition(IValidationContext context) { string cacheId = null; if (context.InstanceToValidate != null) { cacheId = id + context.InstanceToValidate.GetHashCode(); if (context.RootContextData.TryGetValue(cacheId, out var value)) { if (value is bool result) { return(result); } } } var executionResult = predicate((T)context.InstanceToValidate, ValidationContext <T> .GetFromNonGenericContext(context)); if (context.InstanceToValidate != null) { context.RootContextData[cacheId] = executionResult; } return(executionResult); } // Must apply the predicate after the rule has been fully created to ensure any rules-specific conditions have already been applied. foreach (var rule in propertyRules) { rule.ApplySharedCondition(Condition); } return(new ConditionOtherwiseBuilder(_rules, Condition)); }
/// <summary> /// Defines an asynchronous condition that applies to several rules /// </summary> /// <param name="predicate">The asynchronous condition that should apply to multiple rules</param> /// <param name="action">Action that encapsulates the rules.</param> /// <returns></returns> public IConditionBuilder WhenAsync(Func <T, ValidationContext <T>, CancellationToken, Task <bool> > predicate, Action action) { var propertyRules = new List <IValidationRule>(); using (_rules.OnItemAdded(propertyRules.Add)) { action(); } // Generate unique ID for this shared condition. var id = "_FV_AsyncCondition_" + Guid.NewGuid(); async Task <bool> Condition(IValidationContext context, CancellationToken ct) { string cacheId = null; if (context.InstanceToValidate != null) { cacheId = id + context.InstanceToValidate.GetHashCode(); if (context.RootContextData.TryGetValue(cacheId, out var value)) { if (value is bool result) { return(result); } } } var executionResult = await predicate((T)context.InstanceToValidate, ValidationContext <T> .GetFromNonGenericContext(context), ct); if (context.InstanceToValidate != null) { context.RootContextData[cacheId] = executionResult; } return(executionResult); } foreach (var rule in propertyRules) { rule.ApplySharedAsyncCondition(Condition); } return(new AsyncConditionOtherwiseBuilder(_rules, Condition)); }
public virtual void Otherwise(Action action) { var propertyRules = new List <IValidationRule>(); Action <IValidationRule> onRuleAdded = propertyRules.Add; using (_rules.OnItemAdded(onRuleAdded)) { action(); } foreach (var rule in propertyRules) { if (rule is PropertyRule p) { p.ApplySharedAsyncCondition(async(ctx, ct) => !await _condition(ctx, ct)); } else { throw new NotSupportedException("Cannot call the root-level When/Unless methods on rules that don't inherit from PropertyRule"); } } }
/// <summary> /// Defines a condition that applies to several rules /// </summary> /// <param name="predicate">The condition that should apply to multiple rules</param> /// <param name="action">Action that encapsulates the rules.</param> /// <returns></returns> public IConditionBuilder When(Func <T, bool> predicate, Action action) { var propertyRules = new List <IValidationRule>(); Action <IValidationRule> onRuleAdded = propertyRules.Add; using (_rules.OnItemAdded(onRuleAdded)) { action(); } // Generate unique ID for this shared condition. var id = "_FV_Condition_" + Guid.NewGuid(); bool Condition(PropertyValidatorContext context) { if (context.ParentContext.RootContextData.TryGetValue(id, out var value)) { if (value is bool result) { return(result); } } var executionResult = predicate((T)context.Instance); context.ParentContext.RootContextData[id] = executionResult; return(executionResult); } // Must apply the predicate after the rule has been fully created to ensure any rules-specific conditions have already been applied. foreach (var rule in propertyRules) { rule.ApplyCondition(Condition); } return(new ConditionOtherwiseBuilder(_rules, Condition)); }
/// <summary> /// Defines an asynchronous condition that applies to several rules /// </summary> /// <param name="predicate">The asynchronous condition that should apply to multiple rules</param> /// <param name="action">Action that encapsulates the rules.</param> /// <returns></returns> public IConditionBuilder WhenAsync(Func <T, CancellationToken, Task <bool> > predicate, Action action) { var propertyRules = new List <IValidationRule>(); Action <IValidationRule> onRuleAdded = propertyRules.Add; using (_rules.OnItemAdded(onRuleAdded)) { action(); } // Generate unique ID for this shared condition. var id = "_FV_AsyncCondition_" + Guid.NewGuid(); async Task <bool> Condition(PropertyValidatorContext context, CancellationToken ct) { if (context.ParentContext.RootContextData.TryGetValue(id, out var value)) { if (value is bool result) { return(result); } } var executionResult = await predicate((T)context.Instance, ct); context.ParentContext.RootContextData[id] = executionResult; return(executionResult); } foreach (var rule in propertyRules) { rule.ApplyAsyncCondition(Condition); } return(new AsyncConditionOtherwiseBuilder(_rules, Condition)); }