diff --git a/Ifp.Validation/AsyncValidationRule.cs b/Ifp.Validation/AsyncValidationRule.cs
new file mode 100644
index 0000000..1086f46
--- /dev/null
+++ b/Ifp.Validation/AsyncValidationRule.cs
@@ -0,0 +1,115 @@
+using System.Threading.Tasks;
+
+namespace Ifp.Validation
+{
+
+ ///
+ /// The base class for implementing the validation logic. must be implemented with the validation logic.
+ ///
+ /// The type of the object to validate.
+ public abstract class AsyncValidationRule : IAsyncValidationRule
+ {
+ ///
+ /// Checks the and returns a .
+ ///
+ /// The object to validate.
+ /// A that represents the result of the validation.
+ ///
+ /// You can use the extension method to construct a .
+ ///
+ ///
+ /// Indicate success by returning .
+ ///
+ /// public override ValidationOutcome ValidateObject(Animal objectToValidate)
+ /// {
+ /// return ValidationOutcome.Success;
+ /// }
+ ///
+ ///
+ /// Return a by using the method.
+ ///
+ /// public override ValidationOutcome ValidateObject(Animal objectToValidate)
+ /// {
+ /// return ValidationOutcome.Failure(FailureSeverity.Error, "This is an error message.");
+ /// }
+ ///
+ ///
+ /// Return a using the extension method
+ /// .
+ ///
+ /// public override ValidationOutcome ValidateObject(Animal objectToValidate)
+ /// {
+ /// return "This is an error message.".ToFailure(FailureSeverity.Error);
+ /// }
+ ///
+ ///
+ public abstract Task ValidateObjectAsync(T objectToValidate);
+
+ ///
+ /// Returns always false. Override this property and return true if
+ /// the should not proceed validation tests in case this validation rule returns a with .
+ /// This is useful to prevent further processing of rules in cases where all the following rules will also fail. A typical use case is a check for objectToValidate == null.
+ ///
+ public virtual bool CausesValidationProcessToStop => false;
+ }
+
+ ///
+ /// The delegate defines a function that can validate another object.
+ /// The signature is the same as in .
+ ///
+ /// The type of the object to validate.
+ /// The object to validate.
+ /// A that represents the result of the validation.
+ public delegate Task AsyncValidationFunction(T objectToValidate);
+
+ ///
+ /// A class that takes a delegate to perform the validation. This allows to define a validation rule without the need to implement a class that derives from .
+ ///
+ /// The type of the object to validate.
+ public class AsyncValidationRuleDelegate : IAsyncValidationRule
+ {
+
+ ///
+ /// Constructs a new object and takes a delegate that does the validation.
+ ///
+ /// The delegate, that implements the validation logic.
+ ///
+ /// The property is false.
+ ///
+ public AsyncValidationRuleDelegate(AsyncValidationFunction validationFunction)
+ : this(validationFunction, false)
+ {
+ }
+
+ ///
+ /// Constructs a new object and takes a delegate that does the validation.
+ ///
+ /// The delegate, that implements the validation logic.
+ /// Pass true to prevent the to proceed with more .
+ public AsyncValidationRuleDelegate(AsyncValidationFunction validationFunction, bool causesValidationProcessToStop)
+ {
+ ValidationFunction = validationFunction;
+ CausesValidationProcessToStop = causesValidationProcessToStop;
+ }
+
+ ///
+ /// The passes to the constructor.
+ ///
+ protected AsyncValidationFunction ValidationFunction { get; }
+
+ ///
+ /// Implements by delegating to the validation function passed in the constructor.
+ ///
+ /// The object to validate.
+ /// The .
+ public async Task ValidateObjectAsync(T objectToValidate)
+ => await ValidationFunction(objectToValidate);
+
+ ///
+ /// Use the constructor to configure this property.
+ /// Return true if the should not proceed validation tests in case this validation rule returns a with .
+ /// This is useful to prevent further processing of rules in cases where all the following rules will also fail. A typical use case is a check for objectToValidate == null.
+ ///
+ public bool CausesValidationProcessToStop { get; }
+ }
+}
diff --git a/Ifp.Validation/AsyncValidator.cs b/Ifp.Validation/AsyncValidator.cs
new file mode 100644
index 0000000..6a2108d
--- /dev/null
+++ b/Ifp.Validation/AsyncValidator.cs
@@ -0,0 +1,174 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace Ifp.Validation
+{
+
+ ///
+ /// Base class for validators. Those validators usually don't perform validations on there own
+ /// but delegate the validation to one or more objects. These objects perform a single
+ /// isolated validation and the collects the single and wrap them in a .
+ ///
+ /// The type of the object to validate.
+ public abstract class AsyncValidator : IAsyncValidator
+ {
+ ///
+ /// Validate an object and return the objects wrapped in a .
+ ///
+ /// The object to validate.
+ /// The that wraps a several .
+ /// The can be used as a model that can be presented to the user.
+ ///
+ public abstract Task ValidateAsync(T objectToValidate);
+ }
+
+ ///
+ /// A validator that takes a set of objects that implement the interface.
+ /// Use the class or the class as base for the implementation of rules.
+ ///
+ /// The type of the object to validate
+ public class AsyncRuleBasedValidator : AsyncValidator
+ {
+ ///
+ /// Constructs a validator that applies the given validation rules to an object in the given order.
+ ///
+ /// The s to apply to an object.
+ public AsyncRuleBasedValidator(IEnumerable> rules) : this(rules.ToArray()) { }
+
+ ///
+ /// Constructs a validator that applies the given validation rules to an object in the given order.
+ ///
+ /// The s to apply to an object.
+ public AsyncRuleBasedValidator(params IAsyncValidationRule[] rules)
+ {
+ Rules = rules;
+ }
+
+ ///
+ /// The rules passed in the constructor.
+ ///
+ protected IAsyncValidationRule[] Rules { get; }
+
+ ///
+ /// Processes the one after the other and stops if a rule returns a
+ /// with and
+ /// both set to true.
+ ///
+ /// The object to validate.
+ /// A of .
+ protected virtual async Task> ProcessValidationsAsync(T objectToValidate)
+ {
+ var results = new List(Rules.Length);
+ foreach (var rule in Rules)
+ {
+ var ruleResult = await rule.ValidateObjectAsync(objectToValidate);
+ results.Add(ruleResult);
+ if (ruleResult.Severity.IsAnError && rule.CausesValidationProcessToStop)
+ {
+ break;
+ }
+ }
+
+ return results;
+ }
+
+ ///
+ /// Validates an object by applying the rules given in the constructor to the object in the order specified in the constructor./>
+ ///
+ /// The object to validate.
+ /// A that contains the of every applied .
+ public override async Task ValidateAsync(T objectToValidate)
+ => new ValidationSummary(await ProcessValidationsAsync(objectToValidate));
+ }
+
+ ///
+ /// An which combines the of other s.
+ ///
+ /// The type of the object to validate
+ public class AsyncValidatorCombiner : AsyncValidator, IAsyncValidator
+ {
+ ///
+ /// Constructs an that combines the of the in the given order.
+ ///
+ /// The s to combine.
+ public AsyncValidatorCombiner(IEnumerable> validators) : this(validators.ToArray())
+ {
+
+ }
+
+ ///
+ /// Constructs an that combines the of the in the given order.
+ ///
+ /// The s to combine.
+ public AsyncValidatorCombiner(params IAsyncValidator[] validators)
+ {
+ Validators = validators;
+ }
+
+ ///
+ /// The collection of validators that get combined.
+ ///
+ protected IEnumerable> Validators { get; }
+
+ ///
+ /// Validates by calling of all and combining
+ /// their .
+ ///
+ /// The object to validate.
+ ///
+ public override async Task ValidateAsync(T objectToValidate)
+ {
+ var resultList = new List(Validators.Count());
+ foreach (var validator in Validators)
+ {
+ var summary = await validator.ValidateAsync(objectToValidate);
+ resultList.Add(summary);
+ }
+
+ return new ValidationSummary(resultList);
+ }
+ }
+
+ ///
+ /// A validator, that delegates validation to another validator. This can be useful if the objectToValidate needs to be transformed before validation.
+ ///
+ /// The type to which the validation is delegated.
+ /// The type that this validator can validate.
+ public class AsyncDelegateValidator : IAsyncValidator
+ {
+ ///
+ /// Creates a that takes an and a from
+ /// to . The implements .
+ ///
+ /// An existing for .
+ /// An from to .
+ public AsyncDelegateValidator(IAsyncValidator validator, Func selector)
+ {
+ Validator = validator;
+ Selector = selector;
+ }
+
+ ///
+ /// The validator to which the validation is delegated
+ ///
+ protected IAsyncValidator Validator { get; }
+
+ ///
+ /// The function that transforms objectToValidate from to .
+ ///
+ protected Func Selector { get; }
+
+ ///
+ /// Validates an of type by transforming it to and delegating
+ /// validation to .
+ ///
+ /// The object to validate.
+ /// A representing the result of a validation.
+ public async Task ValidateAsync(U objectToValidate)
+ {
+ return await Validator.ValidateAsync(Selector(objectToValidate));
+ }
+ }
+}
diff --git a/Ifp.Validation/IAsyncValidationRule.cs b/Ifp.Validation/IAsyncValidationRule.cs
new file mode 100644
index 0000000..a089d0e
--- /dev/null
+++ b/Ifp.Validation/IAsyncValidationRule.cs
@@ -0,0 +1,30 @@
+using System.Threading.Tasks;
+
+namespace Ifp.Validation
+{
+ ///
+ /// Classes that validate other objects should implement this interface.
+ /// Classes that implement this interface can be combined to rules sets by the .
+ ///
+ /// The type of the object to validate.
+ ///
+ /// You should not implement this interface directly. Use as base class instead.
+ ///
+ ///
+ ///
+ public interface IAsyncValidationRule
+ {
+ ///
+ /// Checks the and returns a .
+ ///
+ /// The object to validate.
+ /// A that represents the result of the validation.
+ Task ValidateObjectAsync(T objectToValidate);
+
+ ///
+ /// Returns true if the should not proceed validation tests in case the validation returns a with .
+ /// This is useful to prevent further processing of rules in cases where all the following rules will also fail. A typical use case is a check for objectToValidate == null.
+ ///
+ bool CausesValidationProcessToStop { get; }
+ }
+}
diff --git a/Ifp.Validation/IAsyncValidator.cs b/Ifp.Validation/IAsyncValidator.cs
new file mode 100644
index 0000000..e48d9a4
--- /dev/null
+++ b/Ifp.Validation/IAsyncValidator.cs
@@ -0,0 +1,21 @@
+using System.Threading.Tasks;
+
+namespace Ifp.Validation
+{
+ ///
+ /// A validator takes an object of type and performs a validation. The result of the validation is represented by a collection
+ /// of wrapped in a .
+ ///
+ /// The type of the object to validate.
+ public interface IAsyncValidator
+ {
+ ///
+ /// Validate an object and return the objects wrapped in a .
+ ///
+ /// The object to validate.
+ /// The that wraps a several .
+ /// The can be used as a model that can be presented to the user.
+ ///
+ Task ValidateAsync(T objectToValidate);
+ }
+}
diff --git a/Ifp.Validation/IValidationRule.cs b/Ifp.Validation/IValidationRule.cs
new file mode 100644
index 0000000..428a704
--- /dev/null
+++ b/Ifp.Validation/IValidationRule.cs
@@ -0,0 +1,28 @@
+namespace Ifp.Validation
+{
+ ///
+ /// Classes that validate other objects should implement this interface.
+ /// Classes that implement this interface can be combined to rules sets by the .
+ ///
+ /// The type of the object to validate.
+ ///
+ /// You should not implement this interface directly. Use as base class instead.
+ ///
+ ///
+ ///
+ public interface IValidationRule
+ {
+ ///
+ /// Checks the and returns a .
+ ///
+ /// The object to validate.
+ /// A that represents the result of the validation.
+ ValidationOutcome ValidateObject(T objectToValidate);
+
+ ///
+ /// Returns true if the should not proceed validation tests in case the validation returns a with .
+ /// This is useful to prevent further processing of rules in cases where all the following rules will also fail. A typical use case is a check for objectToValidate == null.
+ ///
+ bool CausesValidationProcessToStop { get; }
+ }
+}
diff --git a/Ifp.Validation/Ifp.Validation.csproj b/Ifp.Validation/Ifp.Validation.csproj
index 7f1ba7c..809fd01 100644
--- a/Ifp.Validation/Ifp.Validation.csproj
+++ b/Ifp.Validation/Ifp.Validation.csproj
@@ -16,13 +16,13 @@
true
snupkg
validation;valid;input;dependency injection;testable;extensible;rules;rules engine
- New in version 1.5: Added DelegateValidator<T, U>
+ New in version 1.6: Added Async support
https://cdn1.iconfinder.com/data/icons/material-core/20/check-circle-outline-32.png
https://github.com/ifpanalytics/Ifp.Validation
MIT
git
https://github.com/ifpanalytics/Ifp.Validation
- 1.5.0
+ 1.6.0
true
@@ -42,10 +42,12 @@
+
+
diff --git a/Ifp.Validation/ValidationRule.cs b/Ifp.Validation/ValidationRule.cs
index 35bc882..6b05cdc 100644
--- a/Ifp.Validation/ValidationRule.cs
+++ b/Ifp.Validation/ValidationRule.cs
@@ -1,30 +1,5 @@
namespace Ifp.Validation
{
- ///
- /// Classes that validate other objects should implement this interface.
- /// Classes that implement this interface can be combined to rules sets by the .
- ///
- /// The type of the object to validate.
- ///
- /// You should not implement this interface directly. Use as base class instead.
- ///
- ///
- ///
- public interface IValidationRule
- {
- ///
- /// Checks the and returns a .
- ///
- /// The object to validate.
- /// A that represents the result of the validation.
- ValidationOutcome ValidateObject(T objectToValidate);
-
- ///
- /// Returns true if the should not proceed validation tests in case the validation returns a with .
- /// This is useful to prevent further processing of rules in cases where all the following rules will also fail. A typical use case is a check for objectToValidate == null.
- ///
- bool CausesValidationProcessToStop { get; }
- }
///
/// The base class for implementing the validation logic. must be implemented with the validation logic.