wip
This commit is contained in:
@@ -3,32 +3,24 @@ using System.Linq.Expressions;
|
||||
|
||||
namespace Toolkit.Foundation;
|
||||
|
||||
public class Validation(IValidatorCollection validators) :
|
||||
IValidation
|
||||
public class Validation(IValidatorCollection validators) : IValidation
|
||||
{
|
||||
private readonly ValidationErrorCollection errors = [];
|
||||
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
public IReadOnlyIndexDictionary<string, string> Errors =>
|
||||
public IReadOnlyIndexDictionary<string, string> Errors =>
|
||||
new ReadOnlyIndexDictionary<string, string>(errors);
|
||||
|
||||
public bool HasErrors =>
|
||||
Errors.Count > 0;
|
||||
public bool HasErrors => Errors.Count > 0;
|
||||
|
||||
internal IValidatorCollection Validators { get; } = validators;
|
||||
|
||||
public void Add<TProperty>(Expression<Func<TProperty>> property,
|
||||
ValidationRule[] rules,
|
||||
ValidationTrigger trigger = ValidationTrigger.Deferred)
|
||||
public void Add<TProperty>(Expression<Func<TProperty>> property, ValidationRule[] rules, ValidationTrigger trigger = ValidationTrigger.Deferred)
|
||||
{
|
||||
string? name = GetPropertyName(property);
|
||||
string name = GetPropertyName(property);
|
||||
Validators.Add(name, new Validator(name, rules));
|
||||
|
||||
if (trigger is ValidationTrigger.Immediate)
|
||||
{
|
||||
_ = Validate(name);
|
||||
}
|
||||
if (trigger == ValidationTrigger.Immediate) _ = Validate(name);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
@@ -37,93 +29,64 @@ public class Validation(IValidatorCollection validators) :
|
||||
OnPropertyChanged(nameof(Errors), null, null);
|
||||
}
|
||||
|
||||
public virtual void OnPropertyChanged(string propertyName,
|
||||
object? before, object? after)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
public Task<bool> Validate<TProperty>(Expression<Func<TProperty>> property, ValidationRule[] rules) =>
|
||||
ValidateInternal(new Validator(GetPropertyName(property), rules), GetPropertyName(property));
|
||||
|
||||
public async Task<bool> Validate<TProperty>(Expression<Func<TProperty>> property,
|
||||
ValidationRule[] rules)
|
||||
{
|
||||
string? name = GetPropertyName(property);
|
||||
Validator validator = new(name, rules);
|
||||
public Task<bool> Validate(string name, ValidationRule[] rules) =>
|
||||
ValidateInternal(new Validator(name, rules), name);
|
||||
|
||||
Clear(name);
|
||||
|
||||
(bool isValid, string? message) = await validator.TryValidate();
|
||||
|
||||
if (!isValid)
|
||||
{
|
||||
errors[name] = message ?? "";
|
||||
}
|
||||
|
||||
OnPropertyChanged(nameof(Errors), null, null);
|
||||
OnPropertyChanged(nameof(HasErrors), null, null);
|
||||
|
||||
return !HasErrors;
|
||||
}
|
||||
|
||||
public async Task<bool> Validate(string name)
|
||||
{
|
||||
Clear(name);
|
||||
|
||||
if (Validators.TryGet(name, out Validator? validator))
|
||||
{
|
||||
if (validator is not null)
|
||||
{
|
||||
(bool isValid, string? message) = await validator.TryValidate();
|
||||
if (!isValid)
|
||||
{
|
||||
errors[name] = message ?? "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OnPropertyChanged(nameof(Errors), null, null);
|
||||
OnPropertyChanged(nameof(HasErrors), null, null);
|
||||
|
||||
return !HasErrors;
|
||||
}
|
||||
public Task<bool> Validate(string name) =>
|
||||
Validators.TryGet(name, out var validator) && validator != null
|
||||
? ValidateInternal(validator, name)
|
||||
: Task.FromResult(true);
|
||||
|
||||
public async Task<bool> Validate()
|
||||
{
|
||||
Clear();
|
||||
|
||||
foreach (Validator? validator in Validators)
|
||||
foreach (var validator in Validators)
|
||||
{
|
||||
if (validator.PropertyName is string name)
|
||||
{
|
||||
(bool isValid, string? message) = await validator.TryValidate();
|
||||
if (!isValid)
|
||||
{
|
||||
errors[name] = message ?? "";
|
||||
}
|
||||
if (!isValid) errors[name] = message ?? string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
OnPropertyChanged(nameof(Errors), null, null);
|
||||
OnPropertyChanged(nameof(HasErrors), null, null);
|
||||
|
||||
return !HasErrors;
|
||||
}
|
||||
|
||||
private async Task<bool> ValidateInternal(Validator validator, string name)
|
||||
{
|
||||
Clear(name);
|
||||
|
||||
(bool isValid, string? message) = await validator.TryValidate();
|
||||
if (!isValid) errors[name] = message ?? string.Empty;
|
||||
|
||||
OnPropertyChanged(nameof(Errors), null, null);
|
||||
OnPropertyChanged(nameof(HasErrors), null, null);
|
||||
return isValid;
|
||||
}
|
||||
|
||||
private void Clear(string name)
|
||||
{
|
||||
if (Errors.ContainsKey(name))
|
||||
if (errors is not null && errors.ContainsKey(name))
|
||||
{
|
||||
errors.Remove(name);
|
||||
OnPropertyChanged(nameof(Errors), null, null);
|
||||
}
|
||||
}
|
||||
|
||||
private string GetPropertyName<T>(Expression<Func<T>> expression)
|
||||
{
|
||||
return expression.Body switch
|
||||
private static string GetPropertyName<T>(Expression<Func<T>> expression) =>
|
||||
expression.Body switch
|
||||
{
|
||||
MemberExpression memberExpression => memberExpression.Member.Name,
|
||||
UnaryExpression unaryExpression when unaryExpression.Operand is MemberExpression operand => operand.Member.Name,
|
||||
_ => string.Empty
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void OnPropertyChanged(string propertyName, object? before, object? after) =>
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user