codaza
5.34K subscribers
41 photos
27 links
Канал о разработке на платформе .NET с использованием языка программирования C#. Рассматриваются актуальные подходы и современные методологии разработки.

YouTube:
https://www.youtube.com/c/codaza-channel

Контакты:
codaza.channel@gmail.com
Download Telegram
#капитану_на_заметку

Всем привет!

Entity Framework Core — суперпопулярное решение для работы с базами данных в ASP.NET. При исполнении запросов к базе данных, нередко появляются самые разные ошибки ("Timeout expired", "Transaction was deadlocked" и пр.). Обычным решением в борьбе с такими ошибками, является применение политики повторов. Проще говоря, делается повторная попытка выполнения SQL-запроса через некоторый Timeout.

Для решения этой несложной задачи, начинающими (и не очень 😉) разработчиками, придумывается огромное количество "велосипедов". Однако существует стандартное решение — EnableRetryOnFailure. Данный метод позволяет настроить контекст на использование стратегии повторов. Это делается очень просто в файле Program.cs.

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

Подробнее можно прочитать в официальной документации.

-1 велосипед, который так и тянет написать
#капитану_на_заметку

Всем привет!

Мы постоянно пользуемся конфигурационными файлами в наших приложениях. В конфигах мы храним строку соединения с базой данных, токены, логины и прочее. Бывает так, что конфигурация содержит в себе два и более логически связанных параметра. Например, такое может произойти, когда нам нужно иметь возможность задать значения для логина и пароля от какого-нибудь API.

В таких случаях, в appsettings.json, параметры следует выделять в отдельную логическую секцию. Далее, чтобы каждый раз не запрашивать параметры по одному так:

configuration.GetValue<string>("MyConfig:Parameter1");

существует очень удобный способ проецирования вложенной структуры конфигурационного файла, на класс в C#. Для этого нужно выполнить 4 простых шага (см. картинку). После чего, значения параметров будут удобно расположены в объекте.

Такой подход существенно упрощает работу с вложенными структурами в конфигурации вашего приложения.

Вот и всё. Вы великолепны! 🍸

+1 к простым решениям
#капитану_на_заметку

Всем привет!

Большинство web-сервисов предоставляют возможности для интеграции через REST API. За примерами далеко ходить не надо: Google, GitHub, YouTube, Facebook и много-много других — все предоставляют возможность взаимодействия через некоторое API.

Читая документацию на API, вы можете столкнуться с требованием к частоте запросов. Например, максимальная частота запросов не должна превышать 55 в секунду с одного IP-адреса.

Главный вопрос для нас: как добиться выполнения этих требований быстро и просто? Желательно еще, чтобы без смс и регистрации 😉

Существует очень классная библиотека — RateLimiter. Вам просто нужно завести некоторую переменную-ограничитель с указанием той периодичности, которая требуется и дальше пользоваться ей везде перед запросом. Причем вы можете организовывать составные ограничители (например, не более 10 запросов в секунду + не более 1000 запросов в сутки).

Познакомиться подробнее с RateLimiter можно тут.

+1 в сундучок с инструментами юного разработчика
#капитану_на_заметку

Всем привет!

Комментирование исходного кода — это здорово! Открыл исходник и вот он комментарий. Но как прокомментировать SQL-запрос, отправляемый к базе данных, когда мы используем Entity Framework?

Запросы к базе данных могут анализироваться не только разработчиком приложения, но и администратором базы данных. Хотелось бы показать всем разработчикам цель того или иного SQL-запроса без длительного анализа.

Entity Framework предлагает отличный метод TagWith(), который поможет добавить комментарий к SQL-запросу. Комментарий поможет раскрыть намерение запроса и поможет при анализе не только вам, но и разработчикам баз данных.

Вот и всё. Вы и ваша команда великолепны! 🍸

+1 к искусству качественного логирования
#капитану_на_заметку

Всем привет!

Нельзя сказать, что генерация исключений в C# выглядит изящно. Чаще всего это громоздкие конструкции, которые выражают несложную логику, но делают это максимально неуклюже. Естественно, это мешает спокойному восприятию кода в целом.

Возможно, когда-нибудь, это поправят в старших версиях C#. Но что мы можем с этим сделать прямо сегодня и сейчас?

Существует классная библиотека, которая называется Throw. С её помощью, генерация исключений выполняется максимально просто и интуитивно понятно. Пример на картинке — это лишь малая часть возможностей. Например, там есть такие классные штуки как:

name.Throw().IfEmpty();
name.Throw().IfNotContains("substring");

и многое другое.

Ловите ссылку на GitHub Throw тут.

+1 к чистой работе с исключениями
#капитану_на_заметку

Всем привет!

Мне нравится использовать подход Code First. Особенно удобно использовать этот подход при реализации небольших микросервисов с несложной бизнес-логикой.

Одна из проблем, которую мне нередко приходится наблюдать при проведении code review — отсутствие ограничений на строковые значения. Если не указать ограничение строки явно, то все string будут интерпретированы Entity Framework Core в SQL как NVARCHAR(MAX).

Использование NVARCHAR(MAX) везде и всюду плохо по многим причинам, главная из которых — снижение производительности базы данных.

Как это исправить быстро, без смс и регистрации? Просто укажите над свойством атрибут [MaxLength(n)], где n - длина строки, которая вас устраивает.

Вот и всё. Теперь ваши сервисы будут работать быстрее, выше, сильнее.

+1 к грамотному использованию Code First
#капитану_на_заметку

Всем привет!

Рефакторить код и визуально уменьшать синтаксические конструкции C# с помощью ReSharper может быть весело. Я очень люблю это делать!

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

Одним из таких рефакторингов является превращение lambda expression 👉 method group. Действительно, method group выглядит гораздо привлекательнее, но lambda expression может кэшироваться средой выполнения .NET, что избавляет от лишних выделений в оперативной памяти.

Не то чтобы нужно срочно бежать и менять всё на лямбды, но бдительность терять не стоит 👀

+1 к подозрительности при рефакторинге
#капитану_на_заметку

Всем привет! 👻

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

Более-менее опытный разработчик без проблем использует ключевые слова (const, readonly, init и пр.) для указания своих намерений в отношении переменных класса. Но вот с коллекциями это часто не так, а ведь они тоже могут быть неизменными, и мы обязаны показать это намерение. Ключевого слова readonly тут явно недостаточно.

Просто скажите, что собираетесь использовать коллекцию только для чтения IReadOnlyList<T>. Теперь любые попытки изменения коллекции станут невозможными еще на этапе компиляции, а ваше намерение чётким и ясным.

+1 к коду, за который тебя не будут искать

Счастливого Хэллоуина! 🎃