lundi 14 août 2017

Specification pattern async

I'm trying to apply Specification pattern to my validation logic. But I have some problems with async validation.

Let's say I have an entity AddRequest (has 2 string property FileName and Content) that need to be validated.

I need to create 3 validators:

  1. Validate if FileName doesn't contains invalid characters

  2. Validate if Content is correct

  3. Async validate if file with FileName is exists on the database. In this case I should have something like Task<bool> IsSatisfiedByAsync

But how can I implement both IsSatisfiedBy and IsSatisfiedByAsync? Should I create 2 interfaces like ISpecification and IAsyncSpecification or can I do that in one?

My version of ISpecification (I need only And)

    public interface ISpecification
    {
        bool IsSatisfiedBy(object candidate);
        ISpecification And(ISpecification other);
    }

AndSpecification

public class AndSpecification : CompositeSpecification 
{
    private ISpecification leftCondition;
    private ISpecification rightCondition;

    public AndSpecification(ISpecification left, ISpecification right) 
    {
        leftCondition = left;
        rightCondition = right;
    }

    public override bool IsSatisfiedBy(object o) 
    {
        return leftCondition.IsSatisfiedBy(o) && rightCondition.IsSatisfiedBy(o);
    }
}

To validate if file exists I should use:

 await _fileStorage.FileExistsAsync(addRequest.FileName);

How can I write IsSatisfiedBy for that check if I really need do that async?

For example here my validator (1) for FileName

public class FileNameSpecification : CompositeSpecification 
{
    private static readonly char[] _invalidEndingCharacters = { '.', '/' };

    public override bool IsSatisfiedBy(object o) 
    {
        var request = (AddRequest)o;
        if (string.IsNullOrEmpty(request.FileName))
        {
            return false;
        }
        if (request.FileName.Length > 1024)
        {
            return false;
        }
        if (request.FileName.Contains('\\') || _invalidEndingCharacters.Contains(request.FileName.Last()))
        {
            return false;
        }

        return true
    }
}

Aucun commentaire:

Enregistrer un commentaire