Документация

Koto.Validation

Расширения FluentValidation и CQRS pipeline-поведение.

Использует FluentValidation v12 (Apache 2.0 во всех версиях), зафиксирован на [12.0.0,13.0.0).

Установка

dotnet add package Koto.Validation

Что внутри

ТипНазначение
KotoValidators.MustBeValueObject<T, TSource, TValueObject>Валидирует свойство, вызывая доменную фабрику (Func<TSource, Result<TVO>>) — любой исходный тип: string, int, Guid, …
KotoValidators.MustBeEntity<T, TElement, TEntity>Тот же контракт для фабрик сущностей
KotoValidators.ListMustContainNumberOfItemsПравило min/max количества для коллекций
KotoValidators.NotEmptyWithKotoError / LengthWithKotoErrorВстроенные правила с кодами Errors.General
ValidationBehavior<TRequest, TResponse>Pipeline-middleware — запускает все валидаторы (в т.ч. асинхронные) до хендлера
ServiceCollectionExtensions.AddKotoValidationРегистрирует поведение и сканирует сборки на валидаторы

Использование

Регистрация

builder.Services.AddKotoValidation(typeof(Program).Assembly);
// Регистрирует ValidationBehavior<,> как открытый generic и сканирует IValidator<T> —
// дополнительная регистрация не нужна. Рекомендуемый порядок: Logging → Validation → Transaction.

Валидатор — один источник истины

Логика валидации живёт в доменной фабрике; валидатор только вызывает её:

public sealed class PlaceOrderValidator : AbstractValidator<PlaceOrderCommand>
{
    public PlaceOrderValidator()
    {
        RuleFor(x => x.Email).MustBeValueObject(Email.Create);      // источник — string
        RuleFor(x => x.Quantity).MustBeValueObject(Quantity.Create); // источник — int, подходит любой тип
        RuleFor(x => x.Items).ListMustContainNumberOfItems(1, 100);
        RuleFor(x => x.CustomerId).NotEmpty();
    }
}

Валидаторы индексируются по конкретному типу команды и находятся пайплайном автоматически (диспетчер замыкает ValidationBehavior<,> на PlaceOrderCommand).

Структурированные ошибки

Каждая доменная Error передаётся как структурированное состояние — ValidationFailure.CustomState + ErrorCode — а не как сериализованная строка сообщения. При неудаче ValidationBehavior возвращает Result, несущий одну Error на каждое нарушение валидации, с реальными Code, Message и Field (именем свойства). Ничего не сворачивается в одну строку; HTTP-слой может рендерить RFC 7807 validation problem details по каждому полю (см. Koto.Api.AspNetCore).

Асинхронные правила (MustAsync, CustomAsync) полностью поддерживаются — поведение вызывает ValidateAsync.