我試圖將Specification pattern應用到我的驗證邏輯。但是我有一些異步驗證的問題。規範模式異步
比方說,我有一個實體AddRequest
(有2個字符串屬性文件名和內容)需要驗證。
我需要創建3個驗證:
驗證,如果文件名不包含無效字符
驗證,如果內容是正確的
異步驗證是否與文件名的文件是存在在數據庫上。在這種情況下,我應該有一些像
Task<bool> IsSatisfiedByAsync
但我怎麼能同時實現IsSatisfiedBy
和IsSatisfiedByAsync
?我應該創建2個接口,如ISpecification
和IAsyncSpecification
,或者我可以在一個接口中完成嗎?
我的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);
}
}
要驗證文件是否存在,我應該使用:
await _fileStorage.FileExistsAsync(addRequest.FileName);
我怎麼能寫IsSatisfiedBy
爲檢查,如果我真的需要做異步?
例如我在這裏的驗證器(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
'request.FileName.Length> 1024'之前是否必須執行'string.IsNullOrEmpty(request.FileName)'?它不能是異步 – ByeBye
@ByeBye你在說什麼? 'string.IsNullOrEmpty(request.FileName)'在'request.FileName.Length> 1024'之前執行'看代碼 –