Как стать автором
Обновить
5
0
Олег @VolshRus

backend-разработчик

Отправить сообщение

Печаль в том, что все вышесказанное относится только к новым проектам. Если брать практически любой существующий, то окажется, что в базе уже лежит N тысяч невалидных данных, которые всё-таки нужно показывать пользователю (в надежде, что он их распознает). И тогда все эти истории с типизированными классами идут лесом... а жаль.

Рад, что альма матер развивается. Но все же рекомендую заменить фотографию с лекции: открытый на экране pdf со сканом и выключенные мониторы студентов говорят слишком много…
  1. Вместо двух профайлов лучше использовать IConfiguration — вам ведь придется иногда менять лимиты и желательно без перекомпиляции.
  2. А вот для валидаторов использовать стандартный интерфейс бы не помешало.
  3. Когда создаёте директорию, проверять её существование не надо — ошибки не будет.
  4. Не работал с этой либой, но немного напрягает обработка изображения прямо в запросе. При нагрузке запросы будут копиться и быстро уронят вам сервер. Выглядит так, что вам нужен отдельный асинхронный конвеер для обработки изображений, а сервис должен только валидировать файл, загружать его, генерировать имя и пихать в конвеер.
  5. Кстати, загружать файл лучше асинхронно.
Очень ждём появления C# в списке поддерживаемых языков.
Да, HttpClient у вас весьма гибкий) А если, например, мне нужно сказать сваггеру игнорировать поля запросов, помеченные определенным атрибутом — я смогу это сделать?
Сложно комментировать то, чего еще нет… Но вот вам сходу возможная боль.

Допустим, я решил использовать ViennaNET.Logging. Везде, во всем проекте, у меня ILog. И тут проекту потребовался EF Core. Без ViennaNET.ORM (которой пока нет и не уверен, что там этой проблемы не будет) и… и получаю факап, потому потому что EF Core для подключения логгирования запросов хочет классический ILogger. И теперь мне нужно пилить свой ILoggerFactory и пытаться как-то натянуть сову на глобус, т.е. ILog на ILogger.
Думаю, похожий набор библиотек есть в каждой крупной компании. Минус у них общий — кастомность.
Хочешь заинжектить вторую реализацию интерфейса — хрен тебе, наш DI контейнер это не поддерживает, так что страдай. Хочешь два http клиента с разной авторизацией — хрен тебе, страдай. Хочешь… ну вы поняли.
Разумеется все эти хотелки рано или поздно попадут в либу… Но они нужны сейчас, а не поздно или даже рано. И в итоге ты стоишь перед выбором — или отказаться от либы (т.е. ВСЕЙ инфраструктуры) или страдать и костылять.
Публичность свойств в POCO уже давно не является требованием фреймворка — он умеет инициировать поля через конструктор.
Да, еще стоило заметить что мы используем .Net Core 3.1 в «параноидальном» режиме (warning as errors), который очень нервно относится к публичным полям ссылочного типа. Да, можно заткнуть его "= null!", но вот это как раз костыль и путь в Бездну.
Настраивается исключение из публичного описания, точно так же, как это делается для CancellationToken. Стандартный пайплайн, никаких костылей.
Немного не понял. Как FluentValidation отследит некорректный стейт объекта, созданного внутри тестового метода, без конструкции isValid?
А если с ней, то получается, что вводится новое жесткое правило: во всех тестах, где создается какой-либо POCO, должна быть проверка на его валидность. И никакой гарантии соблюдения правила. Нет, можно конечно настроить автоматику… Но это кажется диким оверхедом.

Насчет ActionFilter — в этом случае он как раз не поможет, т.к. срабатывает до и после вызова метода конструктора, а в стандартном кейсе модель конструируется внутри.
Именно поэтому есть Easy Mode без магии. Но если модели запросов без публичных сеттеров, то…
IModelBinderProvider хорошо использовать для каких-то вещей которые есть вот прям в каждм реквесте. По дефолту, мне лично больше нравится расставлять аттрибуты, потом легче читать.

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

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

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

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


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


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

Рад, что сумел помочь!

Информация

В рейтинге
Не участвует
Откуда
Москва, Москва и Московская обл., Россия
Дата рождения
Зарегистрирован
Активность