using System; using System.Collections.Generic; using System.IO.Abstractions; using System.Linq; namespace Quadarax.Foundation.Core.Value { public abstract class Validator { public IList Results { get; private set; } public bool IsSuccess => GetIsSuccess(); protected IFileSystem FileSystem { get; private set; } protected Validator() : this(new FileSystem()) { } protected Validator(IFileSystem fileSystemAbstraction) { FileSystem = fileSystemAbstraction ?? throw new ArgumentNullException(nameof(fileSystemAbstraction)); Results = new List(); } public void Validate(object validatingObject, ValidatorContext context) { Results.Clear(); OnValidate(validatingObject, context); } protected abstract void OnValidate(object validatingObject, ValidatorContext context); public void Reset() { Results.Clear(); } public AggregateException ToAggregateException(bool includeWarning = false, bool inclueInfo = false) { return ToAggregateException(Results, includeWarning, inclueInfo); } public static AggregateException ToAggregateException(IEnumerable results, bool includeWarning = false, bool inclueInfo = false) { var errors = new List(); foreach (var result in results) { if (result.Severity == ValidationResult.ValidationSeverityEnum.Error || result.Severity == ValidationResult.ValidationSeverityEnum.Critical || (includeWarning && result.Severity == ValidationResult.ValidationSeverityEnum.Warning) || (inclueInfo && result.Severity == ValidationResult.ValidationSeverityEnum.Info)) { errors.Add(new Exception(result.Description)); } } if (errors.Count>0) return new AggregateException(errors); return null; } protected void AddResults(IEnumerable resultsToAdd) { ((List)Results).AddRange(resultsToAdd); } protected bool CheckIfEmpty(string name,string value, ValidationResult.ValidationSeverityEnum severity, string description = "") { if (!string.IsNullOrEmpty(value)) return false; if (string.IsNullOrEmpty(description)) description = $"Property named '{name}' must be filled."; Results.Add(new ValidationResult(name, severity, description)); return true; } protected bool CheckIfNull(string name,object value, ValidationResult.ValidationSeverityEnum severity, string description = "") { if (value!=null) return false; if (string.IsNullOrEmpty(description)) description = $"Property named '{name}' must be filled."; Results.Add(new ValidationResult(name, severity, description)); return true; } protected bool CheckIfCollectionEmpty(string name,IEnumerable value, ValidationResult.ValidationSeverityEnum severity, string description = "") { if (value!=null && value.Any()) return false; if (string.IsNullOrEmpty(description)) description = $"Collection named '{name}' must have at least one element."; Results.Add(new ValidationResult(name, severity, description)); return true; } protected bool CheckIfDirectoryNotExists(string name,string value, ValidationResult.ValidationSeverityEnum severity, string description = "") { if (string.IsNullOrEmpty(description)) description = $"Directory '{value}' in property '{name}' doesn't exists or not accessible."; try { if (FileSystem.Directory.Exists(value)) return false; } catch { // ignored } Results.Add(new ValidationResult(name, severity, description)); return true; } protected bool CheckIfNotNumeric(string name,string value, ValidationResult.ValidationSeverityEnum severity, string description = "") { if (string.IsNullOrEmpty(description)) description = $"Property '{name}' must have numeric value."; if (decimal.TryParse(value, out decimal outval)) return false; Results.Add(new ValidationResult(name, severity, description)); return true; } protected bool CheckIfNotGreater(string name,string value, decimal compareValue, bool equalAllowed, ValidationResult.ValidationSeverityEnum severity, string description = "") { if (string.IsNullOrEmpty(description)) description = $"Property '{name}' with value '{value}' must be greater than '{compareValue}'."; if (decimal.TryParse(value, out decimal outval)) { var result = false; if (equalAllowed) result = (outval > compareValue); else result = (outval >= compareValue); if(result) return false; } Results.Add(new ValidationResult(name, severity, description)); return true; } protected bool CheckIfNotGreater(string name, decimal value, decimal compareValue, bool equalAllowed, ValidationResult.ValidationSeverityEnum severity, string description = "") { if (string.IsNullOrEmpty(description)) description = $"Property '{name}' with value '{value}' must be greater than '{compareValue}'."; var result = false; if (equalAllowed) result = (value > compareValue); else result = (value >= compareValue); if (result) return false; Results.Add(new ValidationResult(name, severity, description)); return true; } protected bool CheckIfFileNotExists(string name,string value, ValidationResult.ValidationSeverityEnum severity, string description = "") { if (string.IsNullOrEmpty(description)) description = $"File '{value}' in property '{name}' doesn't exists or not accessible."; try { if (FileSystem.File.Exists(value)) return false; } catch { // ignored } Results.Add(new ValidationResult(name, severity, description)); return true; } protected virtual bool GetIsSuccess() { return !Results.Any(x => /*x.Severity == ValidationResult.ValidationSeverityEnum.Warning ||*/ x.Severity == ValidationResult.ValidationSeverityEnum.Error || x.Severity == ValidationResult.ValidationSeverityEnum.Critical); } } }