Здравствуйте, vaa, Вы писали:
vaa>Вообще о валидацию много копий сломано,
vaa>но общая идея: парсить, а не валидировать
vaa>или еще как принцип "Making illegal states unrepresentable"
vaa>т.е. для arg1 и arg2 если они логически связаны создать valueobject и в конструкторе проверить валидность, а дальше уже передать нормальный объект
vaa>или в нем сделать статик метод подобный тому что выше и сделать конструктор приватным, чтобы не выкидывать исключений из конструктора.
Я тут задумался о реальном примере
Предположим веб-сервис перевода между счетами в банке
Принимаем на вход
record Transaction(string From, string To, decimal Amount)
1) Хотим чтобы номера счетов соответствовали формату, а сумма была положительная, это легко делается атрибутами:
record Transaction([RegularExpression(...)]string From, [RegularExpression(...)]string To, [RangeAttribute(...)]decimal Amount)
2) Хотим чтобы номера счетов были разными
record Transaction([RegularExpression(...)]string From, [RegularExpression(...)]string To, [RangeAttribute(...)]decimal Amount): IValidatableObject
{
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (From == To)
{
yield return new ValidationResult("From and To are same", new[] { nameof(From), nameof(To) });
}
}
}
3) Хотим чтобы счета при конструировании были существующими.
Это атрибутами уже не сделаешь, да IValidatableObject в данном случае так себе решении, так как надо в базу сходить.
Более того проверка счетов уже часть БЛ, и полученные атрибуты счета будут использоваться в дальнейшем для логики перевода.
То есть примерно тот случай, про который пишет топикстартер.
Стоит ли в данном случае изнутри БЛ кидать ArgumentException? Нужно ли в таком случае выдавать 400 клиенту? Или это уже 500 ошибка?