Pull to refresh

Comments 17

UFO just landed and posted this here
IModelBinderProvider хорошо использовать для каких-то вещей которые есть вот прям в каждм реквесте. По дефолту, мне лично больше нравится расставлять аттрибуты, потом легче читать.

Вопрос вкусов. На мой вкус, атрибут нужен если иногда модель берется из одного источника, а иногда из другого. Если же всегда источник один, то постоянное прописывание атрибута только замыливает глаз, как и любой шаблонный код.
Кроме того, мы неизбежно столкнемся со случаем, когда разработчик забудет добавить атрибут.

«Злачные места» аргумент немного странный.

Вы, наверное, правы, стоило объяснить по-другому. Я лишь недавно, с переходом на 3.1, начал закрывать POCO. И результат мне дико понравился. Основная причина — единая инициализация через конструктор, просто не позволяющая создавать некорректный объект.
Классический случай: добавилось новое необязательное поле в запросе. В тестах при этом запросы создаются по-старому, без этого поля. Результат? Тесты не упали, но они уже невалидны.
Кроме того, можно логику, связанную с созданием объекта (например, простановку серверного времени создания) унести в конструктор, а не писать по всему проекту.
Ну и пропавшие бесконечные if (obj.IsValid) радуют неимоверно. Конструктор гарантирует валидность созданной модели, внешние проверки не нужны.
UFO just landed and posted this here
Немного не понял. Как FluentValidation отследит некорректный стейт объекта, созданного внутри тестового метода, без конструкции isValid?
А если с ней, то получается, что вводится новое жесткое правило: во всех тестах, где создается какой-либо POCO, должна быть проверка на его валидность. И никакой гарантии соблюдения правила. Нет, можно конечно настроить автоматику… Но это кажется диким оверхедом.

Насчет ActionFilter — в этом случае он как раз не поможет, т.к. срабатывает до и после вызова метода конструктора, а в стандартном кейсе модель конструируется внутри.
UFO just landed and posted this here
Ох, трюк конечно прикольный, я такого ещё не видел, спасибо что показали, но если бы я увидел такое в реальном проэкте у меня бы возникло много вопросов и смущений.

С таким подходом часть данных доставляется магическим/неявним образом. В итоге просто задебажить контролер не получиться, всегда нужно это учитывать. Кроме того, как писать тесты с такой магией? Запускать весь asp net core runtime чтобы магия начала работать?

Тут было бы логичней вынести все это в отдельные сервисы. Первый отвечает за роботу с другим API, делая все необходимые валидации. Второй уже успользует его и делает свой набор валидаций. Он же пакует все вместе и возвращает. В случае ошибки делать исключение или Maybe<> с кодом ошибки.

Почему же, код прекрасно дебажится. Просто по пайплайну обработки запроса приведенный метод сработает ДО того, как вызовется сам контроллер.


Насчёт юнит тестов: сам класс, понятное дело, тестируется нормально. Если же нужен интеграционный тест, проверяющий что binder запускается (что странно, вы же не проверяете запуск дефолтного binder), то нужна таже самая магия, что и для теста Model Validation с рантаймом. Но на то они и интеграционные тесты.


Ваш вариант, можно сказать, "классический". Я его привел в самом начале статьи. Только вы предлагаете унести и проверки внутрь сервисов. Это частично решит проблему повторяемости, но усугубит самую главную проблему — "размазанность" валидации. Получив некорректный запрос я должен дать отлуп сразу, ещё до его попадания в контроллер, а не где-то в недрах бизнес-логики. На этом принципе построены Authorization и Model Validation в .Net Core и кажется логичным следовать принципам, заложенным в платформу, на которой пишешь.

Попытался понять зачем столько неявной магии с рефлексией и не получилось. Вас потом проклянут, когда попытаются разобраться почему отправляют запрос с одними данными, а приходит с какими-то другими.
Именно поэтому есть Easy Mode без магии. Но если модели запросов без публичных сеттеров, то…
UFO just landed and posted this here
Публичность свойств в POCO уже давно не является требованием фреймворка — он умеет инициировать поля через конструктор.
Да, еще стоило заметить что мы используем .Net Core 3.1 в «параноидальном» режиме (warning as errors), который очень нервно относится к публичным полям ссылочного типа. Да, можно заткнуть его "= null!", но вот это как раз костыль и путь в Бездну.
UFO just landed and posted this here
Как насчет Swagger и клиентской кодогенерации? Какие там костыли придется городить?
Настраивается исключение из публичного описания, точно так же, как это делается для CancellationToken. Стандартный пайплайн, никаких костылей.
Sign up to leave a comment.

Articles