私は検証ロジックにSpecification patternを適用しようとしています。しかし、非同期検証にはいくつか問題があります。仕様パターンasync
私はエンティティAddRequest
(2文字列のプロパティFileNameとContentを持つ)が検証される必要があるとします。
:
検証をファイル名に無効な文字が含まれていない場合
検証内容が正しいかどう
非同期のファイル名を持つファイルが存在しているかどうかを検証データベース上でこの場合、私は
Task<bool> IsSatisfiedByAsync
のようなものを持っている必要がありますが、どのように私はIsSatisfiedBy
とIsSatisfiedByAsync
の両方を実装することができますか? ISpecification
とIAsyncSpecification
のような2つのインターフェイスを作成する必要がありますか?
ファイルは、私が使うべき存在するかどうかを検証しISpecification
の私のバージョン(私は必要とし)
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);
}
}
:
私はIsSatisfiedBy
を書くことができますどのように
await _fileStorage.FileExistsAsync(addRequest.FileName);
は、そのチェックのために私は本当に非同期を行う必要がある場合?例えば
ここに私のバリデータは(1)ファイル名
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
}
}
のために、私はFileExistsSpecificationを作成し、同様に使用する必要があります。
var validations = new FileNameSpecification().And(new FileExistsSpecification());
if(validations.IsSatisfiedBy(addRequest))
{ ... }
しかし、私は非同期が必要な場合どのように私はFileExistsSpecification
を作成することができますか?
、私は非同期に一般化し、同期の契約を破棄したいです。仕様を任意に組み合わせることができ、クライアントが仕様が非同期であるかどうかわからないことを考えると、すべてを非同期であるかのように扱うのが自然であるようです。 – plalx
'string.IsNullOrEmpty(request.FileName)'は 'request.FileName.Length> 1024'より前に実行されなければなりませんか?それは非同期にすることはできません – ByeBye
@ByeByeあなたはどういうことを言っていますか? 'string.IsNullOrEmpty(request.FileName)' 'request.FileName.Length> 1024の前に実行されました。コード –