Мне один коллега уже подсказывал и мне это решение показалось слишком сложным для того, что нам нужно. И не факт, что подошло бы. У нас там целый pipeline в параметрах: несколько команд со своими уникальными параметрами, которые могут повторяться, вызываться в (почти) любом порядке и должны выполняться в итоге по порядку. В общем, ручное решение оказалось очень гибким и легко читаемым. Также чётко указывает на конкретное место ошибки с объяснением.
Можно что угодно использовать в итоге. Главное - парсить параметры сразу и потом уже работать с полученными настройками, а не парсить по ходу дела.
2 Можно создавать объекты руками и передавать их параметрами, но зачем?
3. Новый логер легко использовать в тестах, универсальный, в случае необходимости можно легко поменять библиотеку для логов или добавить дру. Логи стали структурированными.
4. Они все содержат осознанное число строк в зависимости от внутренней логики. Часть из них действительно передаёт ответственность дальше, но это укладывается в логику и помогает лучше понять логику работы сервиса.
12. Да, и я описал, почему и что использую.
14. Конечно, я знаю про JOIN, но не всегда есть возможность это сделать. Например, данные берутся из разных баз. Я хотел показать, что запросы в цикле - это плохо.
16. Сколько записей обработает запрос по неиндексированному полю, чтобы посчитать количество? И сколько для получения первого попавшегося?
До рефакторинга был большой взрыв. Я создал галактики. Чтобы писать сначала тесты, надо хотя бы представлять, как оно всё должно работать. Понимание пришло только после того, как я нарисовал схему взаимодействия всех сервисов.
Если бы там были чистые функции. Там от функционального подхода было лишь использование статических методов повсеместно. Ну, и хотелось предсказуемые для C# тесты написать, а не что-то на стыке. И, всё-таки, не правильно в рамках одной компании делать разные сервисы с очень разными подходами.
Если я пишу какой-то сервис. для API, то я уже знаю о работе DI и что он мне вернёт. Нет смысла придумывать, что там что-то внезапно поменяется и из-за этого засорять конструкторы и тесты кодом, который никогда не будет выполнен и тестирует бесполезные вещи. Это может подойти для библиотеки, но не для класса внутри сервиса с известными параметрами работы. Иначе "на всякий случай" можно и код для .NET Core 3 версии написать, имея сервис на 10-й. Вдруг чего изменится.
Я бы добавил 4-ю: на каждый чих выкидывать исключение вместо возвращения значения.
Например, если DI настроен нормально, то строки типа _imageService = imageService ?? throw new ArgumentNullException(nameof(imageService)); не имеют смысла. Там всегда не null.
А когда исключения лезут в бизнес-логику, то из-за этого обычно код обрастает множеством try-catch на всех уровнях и никогда не знаешь, где именно это исключение будет перехвачено и как обработано. Более того, оно ещё по-разному может обрабатываться в разных местах, что приводит к созданию отдельных исключений и их обработке для какого-то отдельного случая. В одном проекте я со временем удалил с десяток таких одноразовых исключений.
Сейчас один сервис рефакторил. Так там чуть ли не каждый метод обёрнут в исключения, большинство из которых никогда не сработают. Даже вокруг такого кода, который никогда не выбросит исключения.
Если очень надо, а рефакторить такой код дорого, можно сделать PublicException, который будет показывать пользователю ошибку как есть. А всё остальное всё равно должно быть обработано. Желательно в одном месте (ExceptionHandlerMiddleware). Исключение должно сообщать о проблеме в коде/логике, а не быть способом передачи информации.
Тот же необработанный ArgumentException сообщает пользователю название параметра с неверными данными. Зачем это надо? (вопрос риторический)
Звучит как обычный тонкий клиент. Моей первой работой как C#-программиста было развитие подобного десктопного клиента 9.5 лет назад. Внутри не было почти никакой бизнес-логики, управление данными шло через RestAPI.
Какая бы ни была реклама по телевизору, она проходит мимо, если не смотреть телевизор. Но YouTube смотрю и там столько стало нейросетевого шлака, что просто ужас! А которые всё-таки с живыми людьми, даже текст нормально, с выражением прочитать не в состоянии. Как вообще можно захотеть что-то из этого купить, я не представляю.
Так что пойду, пожалуй, почитаю ТВ-парк, чтобы волосы стали мягкими и шелковистыми.
Моё решение быстрое, бесплатное, не требует установки и обучения, выполняет конкретную задачу (в некоторых случаях всего в два клика).Более того, у меня никогда и мысли не возникало об установке этого приложения, не говоря уже о подобном использовании.
Result можно использовать после завершения выполнения потока. Например, после WhenAll. Мы создали пару тасок, закинули их внутрь метода, подождали, вытащили результаты.
ConfigureAwait(false) давно можно использовать только там, где это важно. В большинстве случаев, типа API или веб-сервиса, их можно выкинуть из кода без ущерба производительности, при этом улучшив читаемость. Об этом ещё несколько лет назад писали.
Ещё почему-то обошли стороной GetAwaiter().GetResult().
Ещё не всегда обязательно вызывать await, если метод возвращает Task. Иногда не обязательно ждать выполнения, если логика того не требует. Много чего упущено. В т.ч. и то, что в следующей версии async/await будет сильно переработан.
В статье написано, почему не стоит генерировать через ИИ. К тому же это медленно и не виден результат в процессе. А такая картинка с кодом в качестве КДПВ для статьи про программирование подходит идеально.
Эта, например, отлично подойдёт для статьи о C# для начинающих в качестве иллюстрации:
Это сильно ограничивает использование. А сайт работает везде. К тому же это лежит на GitHub и не требует вообще никаких лишних телодвижений для публикации.
А вот сделать команду для curl, думаю, можно, чтобы в ответе получать готовую картинку. Просто отправляете все параметры прямо в адресной строке.
Мне один коллега уже подсказывал и мне это решение показалось слишком сложным для того, что нам нужно. И не факт, что подошло бы. У нас там целый pipeline в параметрах: несколько команд со своими уникальными параметрами, которые могут повторяться, вызываться в (почти) любом порядке и должны выполняться в итоге по порядку. В общем, ручное решение оказалось очень гибким и легко читаемым. Также чётко указывает на конкретное место ошибки с объяснением.
Можно что угодно использовать в итоге. Главное - парсить параметры сразу и потом уже работать с полученными настройками, а не парсить по ходу дела.
2 Можно создавать объекты руками и передавать их параметрами, но зачем?
3. Новый логер легко использовать в тестах, универсальный, в случае необходимости можно легко поменять библиотеку для логов или добавить дру. Логи стали структурированными.
4. Они все содержат осознанное число строк в зависимости от внутренней логики. Часть из них действительно передаёт ответственность дальше, но это укладывается в логику и помогает лучше понять логику работы сервиса.
12. Да, и я описал, почему и что использую.
14. Конечно, я знаю про JOIN, но не всегда есть возможность это сделать. Например, данные берутся из разных баз. Я хотел показать, что запросы в цикле - это плохо.
16. Сколько записей обработает запрос по неиндексированному полю, чтобы посчитать количество? И сколько для получения первого попавшегося?
До рефакторинга был большой взрыв. Я создал галактики. Чтобы писать сначала тесты, надо хотя бы представлять, как оно всё должно работать. Понимание пришло только после того, как я нарисовал схему взаимодействия всех сервисов.
Если бы там были чистые функции. Там от функционального подхода было лишь использование статических методов повсеместно. Ну, и хотелось предсказуемые для C# тесты написать, а не что-то на стыке. И, всё-таки, не правильно в рамках одной компании делать разные сервисы с очень разными подходами.
Да, верно.
Его не удалить. Он везде. Был, есть и будет.
Если я пишу какой-то сервис. для API, то я уже знаю о работе DI и что он мне вернёт. Нет смысла придумывать, что там что-то внезапно поменяется и из-за этого засорять конструкторы и тесты кодом, который никогда не будет выполнен и тестирует бесполезные вещи. Это может подойти для библиотеки, но не для класса внутри сервиса с известными параметрами работы. Иначе "на всякий случай" можно и код для .NET Core 3 версии написать, имея сервис на 10-й. Вдруг чего изменится.
Я бы добавил 4-ю: на каждый чих выкидывать исключение вместо возвращения значения.
Например, если DI настроен нормально, то строки типа
_imageService = imageService ?? throw new ArgumentNullException(nameof(imageService));не имеют смысла. Там всегда не null.
А когда исключения лезут в бизнес-логику, то из-за этого обычно код обрастает множеством try-catch на всех уровнях и никогда не знаешь, где именно это исключение будет перехвачено и как обработано. Более того, оно ещё по-разному может обрабатываться в разных местах, что приводит к созданию отдельных исключений и их обработке для какого-то отдельного случая. В одном проекте я со временем удалил с десяток таких одноразовых исключений.
Сейчас один сервис рефакторил. Так там чуть ли не каждый метод обёрнут в исключения, большинство из которых никогда не сработают. Даже вокруг такого кода, который никогда не выбросит исключения.
Если очень надо, а рефакторить такой код дорого, можно сделать PublicException, который будет показывать пользователю ошибку как есть. А всё остальное всё равно должно быть обработано. Желательно в одном месте (
ExceptionHandlerMiddleware). Исключение должно сообщать о проблеме в коде/логике, а не быть способом передачи информации.Тот же необработанный ArgumentException сообщает пользователю название параметра с неверными данными. Зачем это надо? (вопрос риторический)
Звучит как обычный тонкий клиент. Моей первой работой как C#-программиста было развитие подобного десктопного клиента 9.5 лет назад. Внутри не было почти никакой бизнес-логики, управление данными шло через RestAPI.
Нет
Какая бы ни была реклама по телевизору, она проходит мимо, если не смотреть телевизор. Но YouTube смотрю и там столько стало нейросетевого шлака, что просто ужас! А которые всё-таки с живыми людьми, даже текст нормально, с выражением прочитать не в состоянии. Как вообще можно захотеть что-то из этого купить, я не представляю.
Так что пойду, пожалуй, почитаю ТВ-парк, чтобы волосы стали мягкими и шелковистыми.
Ну, вот, теперь и Хабр под цензурой.
Моё решение быстрое, бесплатное, не требует установки и обучения, выполняет конкретную задачу (в некоторых случаях всего в два клика).Более того, у меня никогда и мысли не возникало об установке этого приложения, не говоря уже о подобном использовании.
Можно сохранить исходники на этот случай. Только придётся и внешние js тоже загрузить. Зато всегда будет работать.
Добавил текстуры. Кажется, неплохо вышло.
Не всё так однозначно.
Result можно использовать после завершения выполнения потока. Например, после WhenAll. Мы создали пару тасок, закинули их внутрь метода, подождали, вытащили результаты.
ConfigureAwait(false) давно можно использовать только там, где это важно. В большинстве случаев, типа API или веб-сервиса, их можно выкинуть из кода без ущерба производительности, при этом улучшив читаемость. Об этом ещё несколько лет назад писали.
Ещё почему-то обошли стороной GetAwaiter().GetResult().
Ещё не всегда обязательно вызывать await, если метод возвращает Task. Иногда не обязательно ждать выполнения, если логика того не требует. Много чего упущено. В т.ч. и то, что в следующей версии async/await будет сильно переработан.
Проверил. Такой сервис возможен, но не на GitHub. Увы.
В статье написано, почему не стоит генерировать через ИИ. К тому же это медленно и не виден результат в процессе. А такая картинка с кодом в качестве КДПВ для статьи про программирование подходит идеально.
Эта, например, отлично подойдёт для статьи о C# для начинающих в качестве иллюстрации:
Hello, world
А вот готовая иллюстрация к статье со стихами:
Ахматова
Это сильно ограничивает использование. А сайт работает везде. К тому же это лежит на GitHub и не требует вообще никаких лишних телодвижений для публикации.
А вот сделать команду для curl, думаю, можно, чтобы в ответе получать готовую картинку. Просто отправляете все параметры прямо в адресной строке.
Про текстуры классная идея! Надо посмотреть, что из этого может получиться.