День 1376.
Остановим Овер-Инжиниринг ПО
Можем ли мы, как разработчики приложений, перестать овер-инжинерить ПО? Все мы когда-либо это делали. Вот некоторые из ловушек, в которые мы попадаемся, что приводит к овер-инжинирингу.
1. «Что, если»
Мы делаем предположения о предметной области. Проблема в том, что мы не подтверждаем их, а они могут быть неверными. Мы обнаруживаем пограничный случай, который, нам кажется, нужно решить в коде. На самом деле это происходит настолько редко, что бизнесу не нужно это автоматизировать. Об этом проще уведомить и исправить вручную. Подтвердите предположения и поговорите с бизнесом! Не пишите сложный код, когда в этом нет необходимости.
2. Излишняя забота о технологии
Разработчики любят новые крутые библиотеки, фреймворки и инструменты. Мы можем упустить из виду, зачем вообще пишем код. Мы решаем бизнес-задачи и создаём ценность. Хорошо быть в курсе новейших технологий, чтобы улучшать наши системы. Но мы должны уделять такое же внимание домену, в котором мы работаем. Используйте технологию, которая лучше всего решает проблему.
3. Изобретение велосипедов
Вам случалось работать над системой, где был свой кастомный фреймворк, ORM и т.п.? Скорее всего да. Он было документирован? Скорее всего нет. Обычно доморощенный фреймворк много лет назад написал кто-то, кто больше не работает в компании, а теперь застряли с ним вы. Мы любим технологии, но всё, что вы добавляете, — это сложность.
Хорошим примером является написание собственной библиотеки обмена сообщениями вместо RabbitMQ/AWS SQS/Azure ServiceBus. Люди часто делают это, не осознавая всей сложности, которую нужно реализовать. Вместо этого используйте проверенную на практике библиотеку. Купите готовое, а не усложняйте систему.
4. Недостаток изначального проектирования
Недостаточное понимание предметной области приводит к созданию чрезмерно сложной системы. Это вариант игры «что, если». «Что, если нам нужно сделать X» или «Что, если X изменится, давайте добавим Y». Вам это не понадобится.
Не обязательно надолго садиться за проектирование. Исследуйте предметную область, особенно в проекте с нуля, используя что-то простое, например, Event storming. Нужно понять рабочие процессы и различные точки зрения разных людей в бизнесе.
5. DRY без границ
Отличным примером того, что DRY ушёл не туда, является то, что вещи становятся слишком абстрактными, пытаясь приспособиться под различные варианты использования, что в итоге приводит к огромной сложности.
Например, Службы сущностей (Entity Services). ProductService в системе склада, который содержит всю информацию о продукте: название, цена, стоимость, количество в наличии и т.д.
Проблема в том, понятие продукта на складе существует в нескольких разных контекстах. Отдел продаж волнует цена продажи, закупку волнует стоимость, доставку - количество в наличии. Не существует единой сущности продукта, каждый контекст будет иметь свою концепцию, раскрывающую функциональные возможности и данные, которые имеют к ней отношение.
6. Чрезмерная абстракция
Кажется типичным желание абстрагироваться от сторонней зависимости, библиотеки или инструмента. На первый взгляд это имеет смысл, и вы создаете свою абстракцию, чтобы код вашего приложения зависел от неё, а не от сторонней утилиты. И если вам когда-нибудь понадобится изменить её, то не придётся менять весь код приложения. Звучит разумно?
Однако всё сводится к связанности и управлению ей. Смысл абстракции в том, чтобы упростить базовые концепции, наиболее подходящие для вашего варианта использования. Создание абстракции ограничит вашу способность использовать все возможности, которые зависимость может предложить. Управляйте связанностью! Вертикальные слои и фокус на функционале. Группировка функций по функционалу позволит сузить фокус и принимать локальные решения о том, какие зависимости требуются для каждого функционала.
Источник: https://codeopinion.com/stop-over-engineering-software/
Остановим Овер-Инжиниринг ПО
Можем ли мы, как разработчики приложений, перестать овер-инжинерить ПО? Все мы когда-либо это делали. Вот некоторые из ловушек, в которые мы попадаемся, что приводит к овер-инжинирингу.
1. «Что, если»
Мы делаем предположения о предметной области. Проблема в том, что мы не подтверждаем их, а они могут быть неверными. Мы обнаруживаем пограничный случай, который, нам кажется, нужно решить в коде. На самом деле это происходит настолько редко, что бизнесу не нужно это автоматизировать. Об этом проще уведомить и исправить вручную. Подтвердите предположения и поговорите с бизнесом! Не пишите сложный код, когда в этом нет необходимости.
2. Излишняя забота о технологии
Разработчики любят новые крутые библиотеки, фреймворки и инструменты. Мы можем упустить из виду, зачем вообще пишем код. Мы решаем бизнес-задачи и создаём ценность. Хорошо быть в курсе новейших технологий, чтобы улучшать наши системы. Но мы должны уделять такое же внимание домену, в котором мы работаем. Используйте технологию, которая лучше всего решает проблему.
3. Изобретение велосипедов
Вам случалось работать над системой, где был свой кастомный фреймворк, ORM и т.п.? Скорее всего да. Он было документирован? Скорее всего нет. Обычно доморощенный фреймворк много лет назад написал кто-то, кто больше не работает в компании, а теперь застряли с ним вы. Мы любим технологии, но всё, что вы добавляете, — это сложность.
Хорошим примером является написание собственной библиотеки обмена сообщениями вместо RabbitMQ/AWS SQS/Azure ServiceBus. Люди часто делают это, не осознавая всей сложности, которую нужно реализовать. Вместо этого используйте проверенную на практике библиотеку. Купите готовое, а не усложняйте систему.
4. Недостаток изначального проектирования
Недостаточное понимание предметной области приводит к созданию чрезмерно сложной системы. Это вариант игры «что, если». «Что, если нам нужно сделать X» или «Что, если X изменится, давайте добавим Y». Вам это не понадобится.
Не обязательно надолго садиться за проектирование. Исследуйте предметную область, особенно в проекте с нуля, используя что-то простое, например, Event storming. Нужно понять рабочие процессы и различные точки зрения разных людей в бизнесе.
5. DRY без границ
Отличным примером того, что DRY ушёл не туда, является то, что вещи становятся слишком абстрактными, пытаясь приспособиться под различные варианты использования, что в итоге приводит к огромной сложности.
Например, Службы сущностей (Entity Services). ProductService в системе склада, который содержит всю информацию о продукте: название, цена, стоимость, количество в наличии и т.д.
Проблема в том, понятие продукта на складе существует в нескольких разных контекстах. Отдел продаж волнует цена продажи, закупку волнует стоимость, доставку - количество в наличии. Не существует единой сущности продукта, каждый контекст будет иметь свою концепцию, раскрывающую функциональные возможности и данные, которые имеют к ней отношение.
6. Чрезмерная абстракция
Кажется типичным желание абстрагироваться от сторонней зависимости, библиотеки или инструмента. На первый взгляд это имеет смысл, и вы создаете свою абстракцию, чтобы код вашего приложения зависел от неё, а не от сторонней утилиты. И если вам когда-нибудь понадобится изменить её, то не придётся менять весь код приложения. Звучит разумно?
Однако всё сводится к связанности и управлению ей. Смысл абстракции в том, чтобы упростить базовые концепции, наиболее подходящие для вашего варианта использования. Создание абстракции ограничит вашу способность использовать все возможности, которые зависимость может предложить. Управляйте связанностью! Вертикальные слои и фокус на функционале. Группировка функций по функционалу позволит сузить фокус и принимать локальные решения о том, какие зависимости требуются для каждого функционала.
Источник: https://codeopinion.com/stop-over-engineering-software/
👍9
День 1377. #Книги
Сегодня немного отойду в сторону от дотнета. Но фуллстекам, как я, возможно, пригодится.
Закончил читать книгу «Оптимизация запросов в PostgreSQL» (Домбровская Г., Новиков Б., Бейликова А. — М.: ДМК Пресс, 2022).
Хотя она и про PostgreSQL, вполне будет полезна и работающим с другими БД, и просто разработчикам приложений для понимания сути работы базы данных. Почему что-то медленно и как это ускорить, почему не работает индекс, а когда он, наоборот, вреден. А работающие с PostgreSQL (или переходящие на PostgreSQL с других СУБД, как я) тем более найдут много интересного. Для меня, например, стало откровением, что часто динамический SQL в PostgreSQL выполняется быстрее, чем обычный параметризованный запрос. А всё дело в том, что оптимизации применяются после добавления всех параметров. Таким образом Postgres строит разные планы выполнения в зависимости от полученных параметров. К примеру, когда запрашиваются данные за последний год (относительно много строк таблицы), или за предыдущий день (относительно мало). Параметризованный запрос в этом случае будет иметь один план выполнения для обоих случаев. А динамический – разные, и запрос «за день» будет выполняться гораздо быстрее.
Хотя, конечно, книга не без минусов. Главным из которых можно выделить слабое знание авторами современных ORM-систем, и пассажи вроде «большинство ORM по умолчанию откладывают загрузку, поэтому для получения дочерних элементов сначала выдаётся один запрос в базу данных для родительской записи, а затем по одному запросу для каждой дочерней записи». Правда, оговорюсь, что они тестировали на Hibernate. Возможно, в Java так и происходит.
Чтобы от этого избавиться, целая глава посвящена авторской системе NORM (No-ORM), где в базе создаются DTO типы, которые возвращаются через функции в виде JSON, а потом десериализуются в приложении. Авторы утверждают, что это позволяет ускорить получение данных в 10-50 раз (в это я ещё могу поверить). А также, что это упрощает разработку. Вот это уже очень спорно, учитывая, что на каждый запрос нужно создать иерархию типов в базе, а также функцию со сложным SQL-запросом по извлечению этой иерархии. В общем, я не пробовал и не измерял, но решение кажется довольно спорным. Хотя то, что в сложных случаях чистый SQL будет намного быстрее ORM, – это, конечно, правда.
Как бы то ни было, в целом книга очень полезная, рекомендую к прочтению.
Сегодня немного отойду в сторону от дотнета. Но фуллстекам, как я, возможно, пригодится.
Закончил читать книгу «Оптимизация запросов в PostgreSQL» (Домбровская Г., Новиков Б., Бейликова А. — М.: ДМК Пресс, 2022).
Хотя она и про PostgreSQL, вполне будет полезна и работающим с другими БД, и просто разработчикам приложений для понимания сути работы базы данных. Почему что-то медленно и как это ускорить, почему не работает индекс, а когда он, наоборот, вреден. А работающие с PostgreSQL (или переходящие на PostgreSQL с других СУБД, как я) тем более найдут много интересного. Для меня, например, стало откровением, что часто динамический SQL в PostgreSQL выполняется быстрее, чем обычный параметризованный запрос. А всё дело в том, что оптимизации применяются после добавления всех параметров. Таким образом Postgres строит разные планы выполнения в зависимости от полученных параметров. К примеру, когда запрашиваются данные за последний год (относительно много строк таблицы), или за предыдущий день (относительно мало). Параметризованный запрос в этом случае будет иметь один план выполнения для обоих случаев. А динамический – разные, и запрос «за день» будет выполняться гораздо быстрее.
Хотя, конечно, книга не без минусов. Главным из которых можно выделить слабое знание авторами современных ORM-систем, и пассажи вроде «большинство ORM по умолчанию откладывают загрузку, поэтому для получения дочерних элементов сначала выдаётся один запрос в базу данных для родительской записи, а затем по одному запросу для каждой дочерней записи». Правда, оговорюсь, что они тестировали на Hibernate. Возможно, в Java так и происходит.
Чтобы от этого избавиться, целая глава посвящена авторской системе NORM (No-ORM), где в базе создаются DTO типы, которые возвращаются через функции в виде JSON, а потом десериализуются в приложении. Авторы утверждают, что это позволяет ускорить получение данных в 10-50 раз (в это я ещё могу поверить). А также, что это упрощает разработку. Вот это уже очень спорно, учитывая, что на каждый запрос нужно создать иерархию типов в базе, а также функцию со сложным SQL-запросом по извлечению этой иерархии. В общем, я не пробовал и не измерял, но решение кажется довольно спорным. Хотя то, что в сложных случаях чистый SQL будет намного быстрее ORM, – это, конечно, правда.
Как бы то ни было, в целом книга очень полезная, рекомендую к прочтению.
👍23
День 1378.
.NET Conf 2022. Начало
Вот опять ноябрь, а это значит, выпуск новой версии .NET и посвящённая этому .NET Conf 2022.
https://www.dotnetconf.net/
Вот краткое расписание первого дня по московскому времени (подробное расписание тут). Конференция разбита на тематические блоки (Web, Cloud, Client, General, Blazor, GitHub и т.п.), все доклады по 30 минут.
8 ноября
19:00-20:00 Keynote: Welcome to .NET 7
Web
20:00-20:30 State of ASP.NET Core (Daniel Roth)
20:30-21:00 What's new for Blazor in .NET 7 (Steve Sanderson)
21:00-21:30 Making the Most of Minimal APIs in .NET 7 (Safia Abdalla, Stephen Halter)
21:30-22:00 Building modern high-performance services with ASP.NET Core and .NET 7 (Sebastien Ros)
Cloud
22:00-22:30 State of Azure + .NET (Scott Hunter)
22:30-23:00 The Whirlwind Tour of Building .NET Apps in Azure (Matt Soucoup)
23:00- 23:30 Building Serverless Applications with .NET 7 and Azure functions (Melony Qin, Fabio Cavalcante)
23:30-00:00 Azure Container Apps with .NET (Mike Morton, Anthony Chu)
9 ноября
Client
00:00-00:30 State of .NET MAUI (David Ortinau, Maddy Montaquila)
00:30-01:00 What's new in .NET MAUI and Desktop Apps (Shane Neuville)
01:00-01:30 Performance Improvements in .NET MAUI (Jonathan Peppers)
01:30-02:00 Create native desktop & mobile apps using web skills in Blazor Hybrid (Eilon Lipton, James Montemagno)
.NET Developer Stories
02:00-02:30 .NET at Stack Overflow (Roberta Arcoverde)
02:30-03:00 Using .NET to build the .NET website (Maira Wenzel, Jon Galloway)
03:00-03:30 Microsoft Teams Backend Services - Powered by .NET (Marwa El-Dafrawy)
03:30-04:00 How Halo, Dynamics 365, and Mesh scale to millions with Orleans and you can too! (Brady Gaster, Reuben Bond)
General
04:00-05:30 .NET Conf CodeParty 2022 (Jeffrey T. Fritz)
.NET Conf 2022. Начало
Вот опять ноябрь, а это значит, выпуск новой версии .NET и посвящённая этому .NET Conf 2022.
https://www.dotnetconf.net/
Вот краткое расписание первого дня по московскому времени (подробное расписание тут). Конференция разбита на тематические блоки (Web, Cloud, Client, General, Blazor, GitHub и т.п.), все доклады по 30 минут.
8 ноября
19:00-20:00 Keynote: Welcome to .NET 7
Web
20:00-20:30 State of ASP.NET Core (Daniel Roth)
20:30-21:00 What's new for Blazor in .NET 7 (Steve Sanderson)
21:00-21:30 Making the Most of Minimal APIs in .NET 7 (Safia Abdalla, Stephen Halter)
21:30-22:00 Building modern high-performance services with ASP.NET Core and .NET 7 (Sebastien Ros)
Cloud
22:00-22:30 State of Azure + .NET (Scott Hunter)
22:30-23:00 The Whirlwind Tour of Building .NET Apps in Azure (Matt Soucoup)
23:00- 23:30 Building Serverless Applications with .NET 7 and Azure functions (Melony Qin, Fabio Cavalcante)
23:30-00:00 Azure Container Apps with .NET (Mike Morton, Anthony Chu)
9 ноября
Client
00:00-00:30 State of .NET MAUI (David Ortinau, Maddy Montaquila)
00:30-01:00 What's new in .NET MAUI and Desktop Apps (Shane Neuville)
01:00-01:30 Performance Improvements in .NET MAUI (Jonathan Peppers)
01:30-02:00 Create native desktop & mobile apps using web skills in Blazor Hybrid (Eilon Lipton, James Montemagno)
.NET Developer Stories
02:00-02:30 .NET at Stack Overflow (Roberta Arcoverde)
02:30-03:00 Using .NET to build the .NET website (Maira Wenzel, Jon Galloway)
03:00-03:30 Microsoft Teams Backend Services - Powered by .NET (Marwa El-Dafrawy)
03:30-04:00 How Halo, Dynamics 365, and Mesh scale to millions with Orleans and you can too! (Brady Gaster, Reuben Bond)
General
04:00-05:30 .NET Conf CodeParty 2022 (Jeffrey T. Fritz)
www.dotnetconf.net
.NET Conf 2025
Join the .NET Conf 2025 free virtual event November 11-13 to learn about the newest developments across the .NET platform, open source, and dev tools. Mark your calendar!
👍13
День 1379.
.NET Conf 2022. Продолжение
Трансляция
Второй и третий дни конференции идут без перерыва. Вот краткое расписание второго дня по московскому времени (подробное расписание тут).
9 ноября
Deeper .NET
19:00-19:30 What's New in C# 11 (Mads Torgersen, Dustin Campbell)
19:30-20:00 Performance Improvements in .NET 7 (Stephen Toub)
20:00-20:30 Let's design a new C# language feature! (Jared Parsons)
20:30-21:00 .NET Architects Panel (David Fowler, Mikayla Hutchinson, Damian Edwards)
Blazor
21:00-21:30 .NET ❤️’s WebAssembly in .NET 7 (Daniel Roth)
21:30-22:00 Build an Audio Browser app with Blazor (Steve Sanderson)
22:00-22:30 Testing Blazor Applications with Playwright (Debbie O'Brien, Max Schmitt)
GitHub
22:30-23:00 GitHub Universe + .NET Conf Epic Crossover (Scott Hanselman)
23:00-23:30 Microsoft Dev Box and Azure Deployment Environments for .NET Developers (Anthony Cangialosi)
Power Platform / Teams
23:30-00:00 Boost your .NET productivity with Low Code Tools (Karuana Gatimu, Heather Newman)
10 ноября
00:00-00:30 Rapidly create a front-end for your web APIs with Microsoft Power Apps (Julia Kasper)
00:30-01:00 Building Microsoft Teams Bots with .NET & the Teams Toolkit (Ayca Bas, John Miller)
Windows
01:00-01:30 Building Windows apps with WinUI 3 with .NET (Nick Randolph)
01:30-02:00 Accelerate your WinUI 3 app with the Windows Community Toolkit (Michael Hawker)
02:00-02:30 Modernize your WPF and Windows Forms application with Blazor (Michele Aponte)
Modernization
02:30-03:00 Upgrading from .NET Framework to .NET 7 (Mike Rousos, Taylor Southwick, Olia Gavrysh)
03:00-03:30 Using CoreWCF to unblock modernization of WCF apps (Sam Spencer, Matt Connew)
03:30-04:00 High-performance services with gRPC: What's new in .NET 7 (James Newton-King)
General
04:00-04:30 Upgrading Xamarin apps to .NET MAUI (Sweekriti Satpathy)
04:30-05:00 CSS Techniques for Blazor Developers (Ed Charbeneau)
05:00-05:30 Accepting Payments with Stripe Checkout (Cecil Phillip)
05:30-06:00 The Power of Polyglot Notebooks (Claudia Regio)
06:00-06:30 Slaying Zombie ‘No Repro’ Crashes with Infer# (Matthew Jin, Xin Shi, Xiaoyu Liu, Jason Shaver)
06:30-07:00 .NET Interop Improvements in .NET 7 (Jeremy Koritzinsky)
07:00-07:30 Visual Studio Code for C# Developers (Tim Corey)
07:30-08:00 Migrate Your Legacy ASP.NET Projects to ASP.NET Core Incrementally with YARP (Jonathan "J." Tower)
08:00-08:30 MVVM is easier than ever before with Source Generators, .NET 7, and the MVVM Toolkit (Sergio Pedri)
08:30-09:00 Deep Learning in .NET (Kinfey Lo)
09:00-09:30 T4 goodness with Entity Framework Core 7 (Erik Ejlskov Jensen)
09:30-10:00 Build More Predictable Event-Driven System with CloudEvents, .NET and Azure (Justin Yoo)
10:00-10:30 From RESTful HTTP API to gRPC (Irina Scurtu)
10:00-11:00 Human-readable Razor views with ASP.NET 7 Tag Helpers (Dino Esposito)
.NET Conf 2022. Продолжение
Трансляция
Второй и третий дни конференции идут без перерыва. Вот краткое расписание второго дня по московскому времени (подробное расписание тут).
9 ноября
Deeper .NET
19:00-19:30 What's New in C# 11 (Mads Torgersen, Dustin Campbell)
19:30-20:00 Performance Improvements in .NET 7 (Stephen Toub)
20:00-20:30 Let's design a new C# language feature! (Jared Parsons)
20:30-21:00 .NET Architects Panel (David Fowler, Mikayla Hutchinson, Damian Edwards)
Blazor
21:00-21:30 .NET ❤️’s WebAssembly in .NET 7 (Daniel Roth)
21:30-22:00 Build an Audio Browser app with Blazor (Steve Sanderson)
22:00-22:30 Testing Blazor Applications with Playwright (Debbie O'Brien, Max Schmitt)
GitHub
22:30-23:00 GitHub Universe + .NET Conf Epic Crossover (Scott Hanselman)
23:00-23:30 Microsoft Dev Box and Azure Deployment Environments for .NET Developers (Anthony Cangialosi)
Power Platform / Teams
23:30-00:00 Boost your .NET productivity with Low Code Tools (Karuana Gatimu, Heather Newman)
10 ноября
00:00-00:30 Rapidly create a front-end for your web APIs with Microsoft Power Apps (Julia Kasper)
00:30-01:00 Building Microsoft Teams Bots with .NET & the Teams Toolkit (Ayca Bas, John Miller)
Windows
01:00-01:30 Building Windows apps with WinUI 3 with .NET (Nick Randolph)
01:30-02:00 Accelerate your WinUI 3 app with the Windows Community Toolkit (Michael Hawker)
02:00-02:30 Modernize your WPF and Windows Forms application with Blazor (Michele Aponte)
Modernization
02:30-03:00 Upgrading from .NET Framework to .NET 7 (Mike Rousos, Taylor Southwick, Olia Gavrysh)
03:00-03:30 Using CoreWCF to unblock modernization of WCF apps (Sam Spencer, Matt Connew)
03:30-04:00 High-performance services with gRPC: What's new in .NET 7 (James Newton-King)
General
04:00-04:30 Upgrading Xamarin apps to .NET MAUI (Sweekriti Satpathy)
04:30-05:00 CSS Techniques for Blazor Developers (Ed Charbeneau)
05:00-05:30 Accepting Payments with Stripe Checkout (Cecil Phillip)
05:30-06:00 The Power of Polyglot Notebooks (Claudia Regio)
06:00-06:30 Slaying Zombie ‘No Repro’ Crashes with Infer# (Matthew Jin, Xin Shi, Xiaoyu Liu, Jason Shaver)
06:30-07:00 .NET Interop Improvements in .NET 7 (Jeremy Koritzinsky)
07:00-07:30 Visual Studio Code for C# Developers (Tim Corey)
07:30-08:00 Migrate Your Legacy ASP.NET Projects to ASP.NET Core Incrementally with YARP (Jonathan "J." Tower)
08:00-08:30 MVVM is easier than ever before with Source Generators, .NET 7, and the MVVM Toolkit (Sergio Pedri)
08:30-09:00 Deep Learning in .NET (Kinfey Lo)
09:00-09:30 T4 goodness with Entity Framework Core 7 (Erik Ejlskov Jensen)
09:30-10:00 Build More Predictable Event-Driven System with CloudEvents, .NET and Azure (Justin Yoo)
10:00-10:30 From RESTful HTTP API to gRPC (Irina Scurtu)
10:00-11:00 Human-readable Razor views with ASP.NET 7 Tag Helpers (Dino Esposito)
YouTube
.NET Conf 2022 - Day 2
Join us for the second day of .NET Conf! https://dotnetconf.net
.NET Conf is our annual virtual developer event co-organized by the .NET community and Microsoft and sponsored by the .NET Foundation and ecosystem partners. It is a chance to learn and get…
.NET Conf is our annual virtual developer event co-organized by the .NET community and Microsoft and sponsored by the .NET Foundation and ecosystem partners. It is a chance to learn and get…
👍8
День 1380.
.NET Conf 2022. Окончание
https://youtu.be/ET3wMMEt76I
Краткое расписание заключительного дня по московскому времени (подробное расписание тут):
10 ноября
General
11:00-11:30 Tips and tricks on platform-code implementation in .NET MAUI (Luis Beltran)
11:30-12:00 Aloha .NET MAUI Community Toolkit (Gerald Versluis)
12:00-12:30 Pushing C# to new places with NativeAOT (Kevin Gosse)
12:30-13:00 Authorization in a Distributed / Microservice System (Halil İbrahim Kalkan)
13:00-13:30 Down the Oregon Trail with Functional C# (Simon Painter)
13:30-14:00 .NET 7, Docker, K8S and Azure DevOps (Vahid Farahmandian)
14:00-14:30 Leverage the power of the GPU, DX12 and D2D1 with ease using ComputeSharp (Sergio Pedri)
14:30-15:00 Using Durable Azure Functions in .NET 7 (Niels Filter)
15:00-15:30 Performance tricks I learned from contributing to the Azure .NET SDK (Daniel Marbach)
15:30-16:00 Building a .NET SDK library with Open API and NSwag (Laura Rodriguez)
16:00-16:30 WatchDog: What's New in Open-source Logging (Israel Ulelu, Kelechi Onyekwere)
16:30-17:00 Dynamically adding functionality to ASP.NET Core (Chris Klug)
17:00-17:30 ASP.NET Basics for Experts (Layla Porter)
17:30-18:00 .NET Configuration In Depth (Chris Ayers)
18:00-18:30 Networking in .NET 7.0 (Karel Zikmund)
18:30-19:00 Creating Business Applications Using Azure Maps (Michael Washington)
Linux
19:00-19:30 Building .NET apps on WSL (Scott Hanselman)
19:30-20:00 Using .NET with Chiseled Ubuntu Containers (Richard Lander, Valentin Viennot)
20:00-20:30 .NET GUI Applications for Embedded Linux Using Containers (Matheus Castello)
Data
20:30-21:00 Leveling up data: Upgrade from EF6 to EF7 and blast off! (Arthur Vickers, Shay Rojansky)
21:00-21:30 Navigating Graphs in Azure Cosmos DB using Gremlin.Net (Sarah Dutkiewicz)
21:30-22:00 Event Sourcing with Marten and Postgresql (Jeremy Miller)
ML/AI
22:00-22:30 Announcing ML.NET 2.0 (Luis Quintanilla)
22:30-23:00 Machine learning models with ONNX and .NET (Henk Boelman, Beatriz Stollnitz)
General
23:00-23:30 Lessons learnt using DevContainers and the Azure Developer Cli to code apps anywhere, anytime. (Rory Preddy)
23:30-00:00 Clean Architecture with ASP.NET Core 7 (Steve Smith)
11 ноября
00:00-00:30 .NET 7 on App Service (Byron Tardif, Gaurav Seth)
00:30-01:00 Azure Static Web Apps with Blazor and .NET (Melissa Houghton)
01:00-01:30 Building Accessible Apps with .NET MAUI (Rachel Kang)
01:30-02:00 Performance benefits of .NET 7 for Web Applications (Jérôme Laban)
02:00-02:30 Making Technology More Accessible with .NET and AI (Alex Dunn)
Games
02:30-03:00 Build games with C# and Visual Studio (Jb Evain)
03:00-04:00 The future of .NET in real time 3D applications using Unity (Josh Peterson)
.NET Conf 2022. Окончание
https://youtu.be/ET3wMMEt76I
Краткое расписание заключительного дня по московскому времени (подробное расписание тут):
10 ноября
General
11:00-11:30 Tips and tricks on platform-code implementation in .NET MAUI (Luis Beltran)
11:30-12:00 Aloha .NET MAUI Community Toolkit (Gerald Versluis)
12:00-12:30 Pushing C# to new places with NativeAOT (Kevin Gosse)
12:30-13:00 Authorization in a Distributed / Microservice System (Halil İbrahim Kalkan)
13:00-13:30 Down the Oregon Trail with Functional C# (Simon Painter)
13:30-14:00 .NET 7, Docker, K8S and Azure DevOps (Vahid Farahmandian)
14:00-14:30 Leverage the power of the GPU, DX12 and D2D1 with ease using ComputeSharp (Sergio Pedri)
14:30-15:00 Using Durable Azure Functions in .NET 7 (Niels Filter)
15:00-15:30 Performance tricks I learned from contributing to the Azure .NET SDK (Daniel Marbach)
15:30-16:00 Building a .NET SDK library with Open API and NSwag (Laura Rodriguez)
16:00-16:30 WatchDog: What's New in Open-source Logging (Israel Ulelu, Kelechi Onyekwere)
16:30-17:00 Dynamically adding functionality to ASP.NET Core (Chris Klug)
17:00-17:30 ASP.NET Basics for Experts (Layla Porter)
17:30-18:00 .NET Configuration In Depth (Chris Ayers)
18:00-18:30 Networking in .NET 7.0 (Karel Zikmund)
18:30-19:00 Creating Business Applications Using Azure Maps (Michael Washington)
Linux
19:00-19:30 Building .NET apps on WSL (Scott Hanselman)
19:30-20:00 Using .NET with Chiseled Ubuntu Containers (Richard Lander, Valentin Viennot)
20:00-20:30 .NET GUI Applications for Embedded Linux Using Containers (Matheus Castello)
Data
20:30-21:00 Leveling up data: Upgrade from EF6 to EF7 and blast off! (Arthur Vickers, Shay Rojansky)
21:00-21:30 Navigating Graphs in Azure Cosmos DB using Gremlin.Net (Sarah Dutkiewicz)
21:30-22:00 Event Sourcing with Marten and Postgresql (Jeremy Miller)
ML/AI
22:00-22:30 Announcing ML.NET 2.0 (Luis Quintanilla)
22:30-23:00 Machine learning models with ONNX and .NET (Henk Boelman, Beatriz Stollnitz)
General
23:00-23:30 Lessons learnt using DevContainers and the Azure Developer Cli to code apps anywhere, anytime. (Rory Preddy)
23:30-00:00 Clean Architecture with ASP.NET Core 7 (Steve Smith)
11 ноября
00:00-00:30 .NET 7 on App Service (Byron Tardif, Gaurav Seth)
00:30-01:00 Azure Static Web Apps with Blazor and .NET (Melissa Houghton)
01:00-01:30 Building Accessible Apps with .NET MAUI (Rachel Kang)
01:30-02:00 Performance benefits of .NET 7 for Web Applications (Jérôme Laban)
02:00-02:30 Making Technology More Accessible with .NET and AI (Alex Dunn)
Games
02:30-03:00 Build games with C# and Visual Studio (Jb Evain)
03:00-04:00 The future of .NET in real time 3D applications using Unity (Josh Peterson)
YouTube
.NET Conf 2022 - Day Two After Hours + Day 3
Join us for the third and final day of .NET Conf! https://dotnetconf.net
.NET Conf is our annual virtual developer event co-organized by the .NET community and Microsoft and sponsored by the .NET Foundation and ecosystem partners. It is a chance to learn…
.NET Conf is our annual virtual developer event co-organized by the .NET community and Microsoft and sponsored by the .NET Foundation and ecosystem partners. It is a chance to learn…
👍4
День 1381. #ЗаметкиНаПолях #Юмор
Творим Дичь в C#. Часть 2
В этой короткой серии постов рассмотрим разные странные и зачастую бесполезные вещи, которые можно делать в C#.
Ожидаем всё
Вы не устали писать конструкции вроде
Как бы то ни было, нам нужно написать только один небольшой метод расширения, чтобы эта конструкция работала:
Источник: https://steven-giesel.com/blogPost/5360d1c3-89f6-4a08-9ee3-6ddbe1b44236
Творим Дичь в C#. Часть 2
В этой короткой серии постов рассмотрим разные странные и зачастую бесполезные вещи, которые можно делать в C#.
Ожидаем всё
Вы не устали писать конструкции вроде
await Task.Delay(10);Очень много текста и всё равно единица измерения непонятна. Что если можно было бы сделать следующее:
// Подождем 2 секунды через TimeSpanДа, вы правильно поняли, мы хотим дождаться объекта TimeSpan. И сделать это просто. Снова используем методы расширения. Всё, что мы говорили про foreach, применимо и к await. Он основан на шаблоне. Если у нас есть TaskAwaiter для определённого типа, мы можем ожидать этот тип. Есть хорошая статья от Microsoft, в которой Стивен Тауб рассматривает тему подробнее.
await TimeSpan.FromSeconds(2);
Как бы то ни было, нам нужно написать только один небольшой метод расширения, чтобы эта конструкция работала:
public static class ExtensionsВот и всё! У нас есть неявное преобразование из TimeSpan в TaskAwaiter, что позволяет нам ожидать TimeSpan. Но зачем останавливаться на этом? Мы можем пойти дальше в сторону fluent-интерфейсов и сделать что-нибудь вроде этого:
{
public static TaskAwaiter
GetAwaiter(this TimeSpan ts)
{
return Task.Delay(ts).GetAwaiter();
}
}
await 2.Seconds();Красиво и выразительно. Единственное, что нам нужно сделать здесь, это добавить к имеющемуся выше методу, метод расширения для int, возвращающий TimeSpan:
public static class ExtensionsТаким образом, наш int становится неявным TimeSpan, который можно ожидать, потому что компилятор видит TaskAwaiter. Выглядит гораздо более читаемо, чем await Task.Delay.
{
…
public static TimeSpan Seconds(this int i)
=> TimeSpan.FromSeconds(i);
}
Источник: https://steven-giesel.com/blogPost/5360d1c3-89f6-4a08-9ee3-6ddbe1b44236
👍23👎3
День 1382. #ЧтоНовенького
GitHub Codespaces Доступен Бесплатно для Всех Пользователей GitHub
Все пользователи GitHub могут бесплатно использовать размёщенные на GitHub среды разработки до 60 часов в месяц.
Codespace — это среда разработки, размещённая в облаке. Вы можете настроить свой проект для GitHub Codespaces, добавив файлы конфигурации (известные как контейнеры разработки) в свой репозиторий. Контейнеры разработки создают повторяемую конфигурацию среды разработки для всех пользователей вашего проекта.
Каждый кодспейс работает на виртуальной машине, размещённой на GitHub. Вы можете выбрать тип машины, которую хотите использовать, в зависимости от необходимых вам ресурсов. Доступны различные типы машин, начиная с 2-ядерного процессора, 4 ГБ ОЗУ и 32 ГБ памяти.
Таким образом, можно в браузере с любого устройства открыть свой репозиторий и работать с кодом. Понятно, что при всей видимости полноценного редактора, работать с ним не так удобно, как с реальной IDE. Но всё же, отмазаться из отпуска отсутствием под рукой IDE теперь ещё сложнее. Исправить критический баг теперь можно практически с любого устройства, нужен только интернет.
GitHub Codespaces теперь общедоступен для пользователей планов GitHub Free и GitHub Pro. Пользователям GitHub Free будет выделено до 60 часов бесплатного использования Codespaces в месяц, а пользователям плана GitHub Pro — 90 часов.
Кроме того добавлен ряд новых возможностей:
- Публично доступны в бета-версии IDE JetBrains, включая IntelliJ и PyCharm. Разработчики могут загрузить JetBrains Gateway и установить плагин GitHub Codespaces из JetBrains Marketplace. Редактор Visual Studio Code поддерживается в Codespaces со старта.
- Публично доступны в бета-версии JupyterLab Notebooks.
- Codespaces на GPU доступны в ограниченной бета-версии, предоставляя разработчикам возможность запуска моделей машинного обучения.
- Доступны шаблоны для запуска новых проектов на основе популярных платформ приложений. Правда, .NET шаблонов в списке нет.
- Для организаций добавлен REST API для управления и администрирования кодспейсов.
Источник: https://www.infoworld.com/article/3679948/github-codespaces-freely-available-to-all-github-users.html
GitHub Codespaces Доступен Бесплатно для Всех Пользователей GitHub
Все пользователи GitHub могут бесплатно использовать размёщенные на GitHub среды разработки до 60 часов в месяц.
Codespace — это среда разработки, размещённая в облаке. Вы можете настроить свой проект для GitHub Codespaces, добавив файлы конфигурации (известные как контейнеры разработки) в свой репозиторий. Контейнеры разработки создают повторяемую конфигурацию среды разработки для всех пользователей вашего проекта.
Каждый кодспейс работает на виртуальной машине, размещённой на GitHub. Вы можете выбрать тип машины, которую хотите использовать, в зависимости от необходимых вам ресурсов. Доступны различные типы машин, начиная с 2-ядерного процессора, 4 ГБ ОЗУ и 32 ГБ памяти.
Таким образом, можно в браузере с любого устройства открыть свой репозиторий и работать с кодом. Понятно, что при всей видимости полноценного редактора, работать с ним не так удобно, как с реальной IDE. Но всё же, отмазаться из отпуска отсутствием под рукой IDE теперь ещё сложнее. Исправить критический баг теперь можно практически с любого устройства, нужен только интернет.
GitHub Codespaces теперь общедоступен для пользователей планов GitHub Free и GitHub Pro. Пользователям GitHub Free будет выделено до 60 часов бесплатного использования Codespaces в месяц, а пользователям плана GitHub Pro — 90 часов.
Кроме того добавлен ряд новых возможностей:
- Публично доступны в бета-версии IDE JetBrains, включая IntelliJ и PyCharm. Разработчики могут загрузить JetBrains Gateway и установить плагин GitHub Codespaces из JetBrains Marketplace. Редактор Visual Studio Code поддерживается в Codespaces со старта.
- Публично доступны в бета-версии JupyterLab Notebooks.
- Codespaces на GPU доступны в ограниченной бета-версии, предоставляя разработчикам возможность запуска моделей машинного обучения.
- Доступны шаблоны для запуска новых проектов на основе популярных платформ приложений. Правда, .NET шаблонов в списке нет.
- Для организаций добавлен REST API для управления и администрирования кодспейсов.
Источник: https://www.infoworld.com/article/3679948/github-codespaces-freely-available-to-all-github-users.html
👍7
День 1383. #Оффтоп
Сегодня порекомендую вам очередное видео с просторов ютуба.
Вы когда-нибудь задумывались, как компьютеры в сети синхронизируют между собой время? Ведь просто послать запрос на сервер и получить в ответ какое-то время недостаточно. Никто не знает, сколько времени ушло на пересылку информации, и что за время вы получили. Для людей разница в несколько секунд может не играть решающей роли, но в программном мире всё сложнее. Допустим, один компьютер будет писать в файл, а другой – его читать. Если один ставит временную метку записи, а другой читает её, и она оказывается временем в будущем, то могут возникнуть серьёзные проблемы.
В видео от канала Computerphile, доктор Джулиан Онионс рассказывает про протокол NTP (Network Time Protocol), с помощью которого компьютеры синхронизируют время между собой.
https://www.youtube.com/watch?v=BAo5C2qbLq8
Сегодня порекомендую вам очередное видео с просторов ютуба.
Вы когда-нибудь задумывались, как компьютеры в сети синхронизируют между собой время? Ведь просто послать запрос на сервер и получить в ответ какое-то время недостаточно. Никто не знает, сколько времени ушло на пересылку информации, и что за время вы получили. Для людей разница в несколько секунд может не играть решающей роли, но в программном мире всё сложнее. Допустим, один компьютер будет писать в файл, а другой – его читать. Если один ставит временную метку записи, а другой читает её, и она оказывается временем в будущем, то могут возникнуть серьёзные проблемы.
В видео от канала Computerphile, доктор Джулиан Онионс рассказывает про протокол NTP (Network Time Protocol), с помощью которого компьютеры синхронизируют время между собой.
https://www.youtube.com/watch?v=BAo5C2qbLq8
👍5
День 1384. #ЗаметкиНаПолях #Microservices
Снижаем Проблемы от «Шумного Соседа» в Многопользовательском ПО
В многопользовательской системе множество клиентов совместно используют одни и те же вычислительные ресурсы. Это может привести к проблемам, если один клиент загрузит систему таким объёмом работы, что другие обнаружат снижение производительности. Иногда это называют проблемой «шумного соседа», по аналогии многоквартирным домом, где шумный сосед негативно влияет на жизнь других жильцов. Рассмотрим некоторые приёмы, позволяющие снизить ущерб от «шумного соседа».
1. Масштабирование
В идеальном мире шумный сосед не создаёт проблем, потому что система динамически масштабируется для обработки дополнительной нагрузки. Бессерверные платформы или системы с автоматическим горизонтальным масштабированием обнаруживают, когда нагрузка на API или отставание в очереди становятся слишком большими, и автоматически разворачивают дополнительные серверы.
В реальном мире масштабирования может быть недостаточно. Нужно установить верхние пределы на количество хостов, чтобы не платить огромные счета за облачные вычисления и не перегружать базы данных, которые могут быть не в состоянии справиться со значительно возросшим числом одновременных подключений.
2. API ограничений (Rate-limiting)
Мы можем отклонить некоторые вызовы для определённого клиента, разрешив при этом вызовы от других. Например, можно возвращать код ответа HTTP 429 Too Many Requests с заголовком Retry-After, сообщающим клиенту, когда можно будет повторить попытку.
Реализация ограничений для каждого клиента не всегда тривиальна. Нужно определить, что действительно один клиент монополизировал вычислительные ресурсы. Одним из подходов могут быть квоты, когда каждый клиент получает определённое количество разрешённых операций за период времени, прежде чем его вызовы попадут под ограничение.
.NET 7 включает промежуточное ПО ограничений (см. этот пост пункт 4 https://t.iss.one/NetDeveloperDiary/1487), значительно упрощающее эту задачу.
Недостатком этого подхода является то, что вы фактически лишаете клиентов возможности выполнять операции, что не очень удобно для них.
3. Приоритизация очередей
Альтернативой может быть приём запросов и использование очереди для их асинхронной обработки. Сообщения помещаются в очередь, а обработчик сообщений будет работать с отставанием, в итоге навёрстывая его, когда нагрузка спадёт. Но что, если один клиент добавит миллионы сообщений?
Один из вариантов решения — очередь для каждого клиента. Сообщения из разных очередей можно обрабатывать по очереди или параллельно, гарантируя, что каждый клиент получит равные шансы на обработку своего "первого" сообщения. Но если клиентов много, накладные расходы на одновременное обслуживание множества очередей сами по себе могут быть дорогостоящими и ресурсоёмкими.
Другой подход - «очереди с приоритетом». После определённого порога, каждое следующее сообщение от шумного клиента помещается в очередь с «низким приоритетом» и обрабатывается после обработки всех сообщений из основной очереди.
4. Запланированные задания
Аналогично с запланированными заданиями вроде составления отчётности. Их опасность в том, что одному клиенту нужно выполнить необычно большой объем работы в один конкретный день, что может повлиять на других.
Простой подход здесь заключается в выполнении работы блоками или с ограничением по времени для каждого клиента, а затем перехода к обработке задания другого клиента. Возврат к выполнению задания первого клиента осуществляется после того, как у каждого другого клиента также была возможность запустить свою задачу.
5. Миграция клиентов
В экстремальных обстоятельствах вы можете решить, что конкретный клиент вызывает так много проблем, что его нужно перенести в отдельную систему. Возможно, это слишком крупный клиент, тогда затраты на это окупятся.
Эта задача значительно упрощается, если их данные хранятся в отдельной базе, которую можно просто подключить к другому экземпляру ПО.
Источник: https://markheath.net/post/noisy-neighbour-multi-tenancy
Снижаем Проблемы от «Шумного Соседа» в Многопользовательском ПО
В многопользовательской системе множество клиентов совместно используют одни и те же вычислительные ресурсы. Это может привести к проблемам, если один клиент загрузит систему таким объёмом работы, что другие обнаружат снижение производительности. Иногда это называют проблемой «шумного соседа», по аналогии многоквартирным домом, где шумный сосед негативно влияет на жизнь других жильцов. Рассмотрим некоторые приёмы, позволяющие снизить ущерб от «шумного соседа».
1. Масштабирование
В идеальном мире шумный сосед не создаёт проблем, потому что система динамически масштабируется для обработки дополнительной нагрузки. Бессерверные платформы или системы с автоматическим горизонтальным масштабированием обнаруживают, когда нагрузка на API или отставание в очереди становятся слишком большими, и автоматически разворачивают дополнительные серверы.
В реальном мире масштабирования может быть недостаточно. Нужно установить верхние пределы на количество хостов, чтобы не платить огромные счета за облачные вычисления и не перегружать базы данных, которые могут быть не в состоянии справиться со значительно возросшим числом одновременных подключений.
2. API ограничений (Rate-limiting)
Мы можем отклонить некоторые вызовы для определённого клиента, разрешив при этом вызовы от других. Например, можно возвращать код ответа HTTP 429 Too Many Requests с заголовком Retry-After, сообщающим клиенту, когда можно будет повторить попытку.
Реализация ограничений для каждого клиента не всегда тривиальна. Нужно определить, что действительно один клиент монополизировал вычислительные ресурсы. Одним из подходов могут быть квоты, когда каждый клиент получает определённое количество разрешённых операций за период времени, прежде чем его вызовы попадут под ограничение.
.NET 7 включает промежуточное ПО ограничений (см. этот пост пункт 4 https://t.iss.one/NetDeveloperDiary/1487), значительно упрощающее эту задачу.
Недостатком этого подхода является то, что вы фактически лишаете клиентов возможности выполнять операции, что не очень удобно для них.
3. Приоритизация очередей
Альтернативой может быть приём запросов и использование очереди для их асинхронной обработки. Сообщения помещаются в очередь, а обработчик сообщений будет работать с отставанием, в итоге навёрстывая его, когда нагрузка спадёт. Но что, если один клиент добавит миллионы сообщений?
Один из вариантов решения — очередь для каждого клиента. Сообщения из разных очередей можно обрабатывать по очереди или параллельно, гарантируя, что каждый клиент получит равные шансы на обработку своего "первого" сообщения. Но если клиентов много, накладные расходы на одновременное обслуживание множества очередей сами по себе могут быть дорогостоящими и ресурсоёмкими.
Другой подход - «очереди с приоритетом». После определённого порога, каждое следующее сообщение от шумного клиента помещается в очередь с «низким приоритетом» и обрабатывается после обработки всех сообщений из основной очереди.
4. Запланированные задания
Аналогично с запланированными заданиями вроде составления отчётности. Их опасность в том, что одному клиенту нужно выполнить необычно большой объем работы в один конкретный день, что может повлиять на других.
Простой подход здесь заключается в выполнении работы блоками или с ограничением по времени для каждого клиента, а затем перехода к обработке задания другого клиента. Возврат к выполнению задания первого клиента осуществляется после того, как у каждого другого клиента также была возможность запустить свою задачу.
5. Миграция клиентов
В экстремальных обстоятельствах вы можете решить, что конкретный клиент вызывает так много проблем, что его нужно перенести в отдельную систему. Возможно, это слишком крупный клиент, тогда затраты на это окупятся.
Эта задача значительно упрощается, если их данные хранятся в отдельной базе, которую можно просто подключить к другому экземпляру ПО.
Источник: https://markheath.net/post/noisy-neighbour-multi-tenancy
👍7
День 1385. #ЗаметкиНаПолях #TipsAndTricks
Современные Приёмы в C#. Часть 1
Странно Повторяющийся Обобщённый Паттерн
Название предложено Стивеном Клири по аналогии со «Странно повторяющимся шаблоном» из C++.
Смысл паттерна в том, что интерфейс (или базовый тип) принимает в качестве параметра типа собственный производный тип:
Интерфейс (или базовый тип) также может использовать себя в качестве ограничения обобщения. Иногда это полезно, особенно для базовых типов:
- Базовый тип должен рассматривать экземпляр MyBase<TDerived> (например, this) как производный тип (т. е. (TDerived)this). Это также может возникнуть при передаче this другим методам.
- Базовый тип должен обрабатывать TDerived как MyBase<TDerived>, например, вызывая приватные базовые методы для экземпляра типа TDerived, отличного от this. В этом случае явное приведение не требуется.
Подобно обычным методам интерфейса, Curiously Recurring Generic Pattern может при необходимости повысить безопасность типов методов интерфейса по умолчанию. Это похоже на использование паттерна с базовым типом, за исключением того, что интерфейсы не могут иметь состояния. Иными словами, это позволяет использовать строго типизированные трейты, но не подходит для миксинов.
Как и другие паттерны кода, этот тоже можно использовать не по назначению. Наиболее распространённое неправильное использование – его чрезмерное применение. Кроме того, этот паттерн имеет усложняет код. Здесь нужно найти компромисс между добавляемой ценностью и усложнением поддержки кодовой базы.
Источник: https://blog.stephencleary.com/2022/09/modern-csharp-techniques-1-curiously-recurring-generic-pattern.html
Современные Приёмы в C#. Часть 1
Странно Повторяющийся Обобщённый Паттерн
Название предложено Стивеном Клири по аналогии со «Странно повторяющимся шаблоном» из C++.
Смысл паттерна в том, что интерфейс (или базовый тип) принимает в качестве параметра типа собственный производный тип:
interface IExample<TDerived>Если интерфейс (или базовый тип) хочет использовать полноценный производный тип в качестве параметра метода или возвращаемого значения, то он может сам определить эти методы, не возлагая никакой ответственности на производный тип. Вот пример из .NET BCL:
{ … }
class MyExample : IExample<MyExample>
{ … }
public interface IEquatable<T>Использование:
{
bool Equals(T? other);
}
sealed class MyEquatable :MyEquatable.Equals реализует IEquatable<T>.Equals со строго типизированным аргументом MyEquatable. Без использования паттерна пришлось бы использовать IEquatable (принимая object) и терялась бы безопасность типов и эффективность.
IEquatable<MyEquatable>
{
public bool Equals(MyEquatable? other)
{ … }
}
Интерфейс (или базовый тип) также может использовать себя в качестве ограничения обобщения. Иногда это полезно, особенно для базовых типов:
abstract class MyBase<TDerived>Например, это полезно в Fluent API. В более общем случае ограничение обобщения необходимо в любой из этих ситуаций:
where TDerived : MyBase<TDerived>
{
// Методы могут использовать (TDerived)this
// Полезно при возврате TDerived
public virtual TDerived Get()
=> (TDerived)this;
}
class Derived : MyBase<Derived>
{
// Неявно имеет реализацию
// public Derived Get(), т.к. метод
// базового класса правильно определяет
// тип возвращаемого значения.
// Но может и переопределить его
}
- Базовый тип должен рассматривать экземпляр MyBase<TDerived> (например, this) как производный тип (т. е. (TDerived)this). Это также может возникнуть при передаче this другим методам.
- Базовый тип должен обрабатывать TDerived как MyBase<TDerived>, например, вызывая приватные базовые методы для экземпляра типа TDerived, отличного от this. В этом случае явное приведение не требуется.
Подобно обычным методам интерфейса, Curiously Recurring Generic Pattern может при необходимости повысить безопасность типов методов интерфейса по умолчанию. Это похоже на использование паттерна с базовым типом, за исключением того, что интерфейсы не могут иметь состояния. Иными словами, это позволяет использовать строго типизированные трейты, но не подходит для миксинов.
Как и другие паттерны кода, этот тоже можно использовать не по назначению. Наиболее распространённое неправильное использование – его чрезмерное применение. Кроме того, этот паттерн имеет усложняет код. Здесь нужно найти компромисс между добавляемой ценностью и усложнением поддержки кодовой базы.
Источник: https://blog.stephencleary.com/2022/09/modern-csharp-techniques-1-curiously-recurring-generic-pattern.html
👍14
День 1386. #ЧтоНовенького
Утилита для Создания Токенов JWT на Время Разработки
Допустим, вы создаёте защищённый API. Для аутентификации/авторизации используются JWT. Нужно убедиться, что API отклоняет неправильные или поддельные токены и разрешает доступ с правильными. Можно написать собственный код для генерации токенов JWT или можно зарегистрировать клиентов с нужными параметрами в Identity Server, если он у нас есть.
Однако в .NET 7 появился инструмент dotnet user-jwts. Он помогает создавать и управлять JWT во время разработки для проекта, который мы создаём.
Создадим простой API:
- открытая в корне, которая выдаёт строку "Hello, World!";
- закрытая /secret, выдающая приветствие авторизованному пользователю.
Теперь добавим возможность использовать локальные JWT токены.
Мы можем задавать различные параметры для JWT токена, например, имя пользователя, список клеймов и разрешений (полная документация команды):
Утилита для Создания Токенов JWT на Время Разработки
Допустим, вы создаёте защищённый API. Для аутентификации/авторизации используются JWT. Нужно убедиться, что API отклоняет неправильные или поддельные токены и разрешает доступ с правильными. Можно написать собственный код для генерации токенов JWT или можно зарегистрировать клиентов с нужными параметрами в Identity Server, если он у нас есть.
Однако в .NET 7 появился инструмент dotnet user-jwts. Он помогает создавать и управлять JWT во время разработки для проекта, который мы создаём.
Создадим простой API:
using System.Security.Claims;В нашем API 2 конечные точки:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthorization();
builder.Services
.AddAuthentication("Bearer")
.AddJwtBearer();
var app = builder.Build();
app.MapGet("/", () => "Hello, World!");
app.MapGet("/secret",
(ClaimsPrincipal user) =>
$"Hello {user.Identity?.Name}!")
.RequireAuthorization();
app.Run();
- открытая в корне, которая выдаёт строку "Hello, World!";
- закрытая /secret, выдающая приветствие авторизованному пользователю.
Теперь добавим возможность использовать локальные JWT токены.
dotnet user-jwts createЭта команда создаст токен для текущего пользователя компьютера, а также добавит в файл appsettings.Development.json блок "Authentication" с необходимыми настройками для использования Bearer-аутентификации.
Мы можем задавать различные параметры для JWT токена, например, имя пользователя, список клеймов и разрешений (полная документация команды):
dotnet user-jwts create --name MyTestUser --scope "myapi:secrets"Эта команда создаст пользователя с именем MytestUser и разрешением для "myapi:secrets". Вывод будет примерно такой:
New JWT saved with ID 'd0f7fe96'.Вот и всё. Теперь мы можем использовать любой REST-клиент, вроде Postman, для доступа к закрытой конечной точке. Скопируйте значение Token, выданное утилитой user-jwts. В Postman создайте Get запрос к https://localhost:7107/secret. На вкладке Authorization выберите Type: Bearer Token и вставьте значение токена в поле. Выполните запрос. Он должен выдать код ответа HTTP 200 и ответ:
Name: MyTestUser
Scopes: myapi:secrets
Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVC…
Hello MyTestUser!Источник: https://learn.microsoft.com/en-us/aspnet/core/security/authentication/jwt-authn
👍23
День 1387. #ЗадачиНаСобеседовании
Давненько у нас не было задачек. Сегодня предложу вам подумать над проектированием решения в контексте базы данных. Единственно правильного ответа тут, наверное, нет, просто предлагайте варианты.
Допустим, у нас есть огромная таблица инвентаря товаров в наличии в разных магазинах сети. Т.е. в таблице будет id магазина, артикул товара, количество и прочая информация о товаре. Из неё нас интересуют поля ID магазина и артикул. Таблица несколько раз в день обновляется по мере того, как магазины получают или распродают свой товар и присылают нам остатки.
Задача в следующем. Для клиента сайта требуется организовать «живые» подсказки в строке поиска. То есть по мере того, как клиент печатает артикул (для простоты пусть будет поиск только по артикулу), подсказка под полем показывает доступные артикулы и количество магазинов, в которых они есть в наличии. Например:
Поиск:
Собственно задача. Понятно, что каждый раз запрашивать огромную таблицу слишком затратно. Предположим, что нам достаточно не иметь 100% точной информации в каждую секунду, и этот список должен актуализироваться, скажем, каждые 30 минут.
Фронтенд нас сейчас не интересует. Интересует быстрое получение результата на бэкенде. Как бы вы с точки зрения хранения данных и получения их из базы реализовали такой функционал?
Давненько у нас не было задачек. Сегодня предложу вам подумать над проектированием решения в контексте базы данных. Единственно правильного ответа тут, наверное, нет, просто предлагайте варианты.
Допустим, у нас есть огромная таблица инвентаря товаров в наличии в разных магазинах сети. Т.е. в таблице будет id магазина, артикул товара, количество и прочая информация о товаре. Из неё нас интересуют поля ID магазина и артикул. Таблица несколько раз в день обновляется по мере того, как магазины получают или распродают свой товар и присылают нам остатки.
Задача в следующем. Для клиента сайта требуется организовать «живые» подсказки в строке поиска. То есть по мере того, как клиент печатает артикул (для простоты пусть будет поиск только по артикулу), подсказка под полем показывает доступные артикулы и количество магазинов, в которых они есть в наличии. Например:
Поиск:
ABC
Подсказка:ABC280 - 10 магазиновТ.е. в результате должно быть сгруппированное по артикулу количество магазинов, в которых есть товар.
ABC100 – 5 магазинов
ABC101 – 2 магазина
ABCDEF-92 – 1 магазин
ABC-XYZ – 1 магазин
Собственно задача. Понятно, что каждый раз запрашивать огромную таблицу слишком затратно. Предположим, что нам достаточно не иметь 100% точной информации в каждую секунду, и этот список должен актуализироваться, скажем, каждые 30 минут.
Фронтенд нас сейчас не интересует. Интересует быстрое получение результата на бэкенде. Как бы вы с точки зрения хранения данных и получения их из базы реализовали такой функционал?
👍2
День 1388. #Карьера
6 Принципов Разработки Проектов с Открытым Кодом
Работа над проектом с открытым кодом, будь то в качестве автора, сопровождающего или разработчика, может быть довольно сложной! Сегодня посмотрим, на какие важные уроки можно извлечь при разработке open-source проектов.
1. Документация недооценена
Обычно ПО с открытым кодом создаётся не только для себя. Его будут использовать самые разные пользователи с разным уровнем подготовки. Надлежащая документация поможет им начать работу. В документации можно дать объяснение сложных алгоритмов, продемонстрировать варианты использования и даже разместить интерактивные примеры. Кроме того, написание хорошей документации сокращает время, затрачиваемое на решение проблем. У пользователей будет меньше причин задавать вопросы, если они смогут найти ответы в документации.
2. Сообщество — это всё
Сообщество ваших пользователей является важным компонентом вашего ПО. Мы хотим, чтобы пользователи участвовали в разработке. Взаимодействуя с сообществом, вы побуждаете их делиться проблемами и ошибками, а также пожеланиями и идеями для дальнейшего развития. Многие основные функции проектов с открытым кодом реализуются по настоянию пользователей или даже самими пользователями. Кроме того, они помогают с обнаружением проблем и исправлением ошибок.
3. Это отличная возможность для обучения
Независимо от того, будет ли ваш пакет скачан миллионы или всего пару раз, его создание — отличная возможность узнать больше об открытом коде, модульном тестировании, дизайне API и т.д., чем в повседневной работе.
Существует также огромная возможность обучения от взаимодействия с сообществом. Именно они сообщат вам, какой дизайн им нравится, а какой нет. Иногда одна и та же проблема возникает несколько раз в течение нескольких месяцев. Это указывает на то, что нужно переосмыслить дизайн, поскольку он оказался не таким удобным для пользователей, как вы ожидали.
Кроме того, это прекрасная возможность сотрудничества с другими разработчиками.
4. Это может быть стрессом
Поддержка ПО, ответы на вопросы и участие в обсуждениях могут потребовать много времени и сил. Это определенно помогает, если вы внутренне мотивированы, но всё же требуется довольно много времени, чтобы убедиться, что всё работает как надо. К счастью, вы можете обратиться к сообществу за помощью в ответах на вопросы, или для демонстрации вариантов использования.
5. Звёзды Github - не гарантия качества
Знание того, как часто используется пакет, очень помогает понять, насколько он популярен. Тем не менее, многие по-прежнему используют звёзды на Github, чтобы оценивать качество и популярность.
Однако большое количество звёзд может быть просто результатом правильного маркетинга. Звезда от пользователя даже не означает, что он использовал это ПО или что оно действительно работает. Количество загрузок пакета гораздо лучший показатель. Кроме того, можно посмотреть на количество форков или активность обсуждения.
6. Психология разработки API
Убедитесь, что пакет прост в использовании и установке, что значительно упрощает его внедрение. Когда вы сильно сосредотачиваетесь на дизайне: модульности, слабой связанности и следовании лучшим практикам, - некоторые пакеты становятся просто взрывом мозга при использовании.
Посмотрите на разработку новых функций с точки зрения психологии, и это значительно облегчит понимание того, на чём следует сосредоточиться. Что нужно пользователям? Почему пользователи на самом деле используют этот пакет? Каковы основные недостатки вашего кода?
Потратьте время на то, чтобы понять, как облегчить внедрение вашего пакета для среднестатистического пользователя. Всё это часто сводится к одному правилу: сделайте это супер простым!
Чем сложнее установить и использовать пакет, тем с меньшей вероятностью пользователи будут использовать его в своём рабочем процессе.
Источник: https://towardsdatascience.com/6-lessons-i-learned-from-developing-open-source-projects-4617e26f247c
Автор оригинала: Maarten Grootendorst
6 Принципов Разработки Проектов с Открытым Кодом
Работа над проектом с открытым кодом, будь то в качестве автора, сопровождающего или разработчика, может быть довольно сложной! Сегодня посмотрим, на какие важные уроки можно извлечь при разработке open-source проектов.
1. Документация недооценена
Обычно ПО с открытым кодом создаётся не только для себя. Его будут использовать самые разные пользователи с разным уровнем подготовки. Надлежащая документация поможет им начать работу. В документации можно дать объяснение сложных алгоритмов, продемонстрировать варианты использования и даже разместить интерактивные примеры. Кроме того, написание хорошей документации сокращает время, затрачиваемое на решение проблем. У пользователей будет меньше причин задавать вопросы, если они смогут найти ответы в документации.
2. Сообщество — это всё
Сообщество ваших пользователей является важным компонентом вашего ПО. Мы хотим, чтобы пользователи участвовали в разработке. Взаимодействуя с сообществом, вы побуждаете их делиться проблемами и ошибками, а также пожеланиями и идеями для дальнейшего развития. Многие основные функции проектов с открытым кодом реализуются по настоянию пользователей или даже самими пользователями. Кроме того, они помогают с обнаружением проблем и исправлением ошибок.
3. Это отличная возможность для обучения
Независимо от того, будет ли ваш пакет скачан миллионы или всего пару раз, его создание — отличная возможность узнать больше об открытом коде, модульном тестировании, дизайне API и т.д., чем в повседневной работе.
Существует также огромная возможность обучения от взаимодействия с сообществом. Именно они сообщат вам, какой дизайн им нравится, а какой нет. Иногда одна и та же проблема возникает несколько раз в течение нескольких месяцев. Это указывает на то, что нужно переосмыслить дизайн, поскольку он оказался не таким удобным для пользователей, как вы ожидали.
Кроме того, это прекрасная возможность сотрудничества с другими разработчиками.
4. Это может быть стрессом
Поддержка ПО, ответы на вопросы и участие в обсуждениях могут потребовать много времени и сил. Это определенно помогает, если вы внутренне мотивированы, но всё же требуется довольно много времени, чтобы убедиться, что всё работает как надо. К счастью, вы можете обратиться к сообществу за помощью в ответах на вопросы, или для демонстрации вариантов использования.
5. Звёзды Github - не гарантия качества
Знание того, как часто используется пакет, очень помогает понять, насколько он популярен. Тем не менее, многие по-прежнему используют звёзды на Github, чтобы оценивать качество и популярность.
Однако большое количество звёзд может быть просто результатом правильного маркетинга. Звезда от пользователя даже не означает, что он использовал это ПО или что оно действительно работает. Количество загрузок пакета гораздо лучший показатель. Кроме того, можно посмотреть на количество форков или активность обсуждения.
6. Психология разработки API
Убедитесь, что пакет прост в использовании и установке, что значительно упрощает его внедрение. Когда вы сильно сосредотачиваетесь на дизайне: модульности, слабой связанности и следовании лучшим практикам, - некоторые пакеты становятся просто взрывом мозга при использовании.
Посмотрите на разработку новых функций с точки зрения психологии, и это значительно облегчит понимание того, на чём следует сосредоточиться. Что нужно пользователям? Почему пользователи на самом деле используют этот пакет? Каковы основные недостатки вашего кода?
Потратьте время на то, чтобы понять, как облегчить внедрение вашего пакета для среднестатистического пользователя. Всё это часто сводится к одному правилу: сделайте это супер простым!
Чем сложнее установить и использовать пакет, тем с меньшей вероятностью пользователи будут использовать его в своём рабочем процессе.
Источник: https://towardsdatascience.com/6-lessons-i-learned-from-developing-open-source-projects-4617e26f247c
Автор оригинала: Maarten Grootendorst
👍6
День 1389. #Оффтоп #Карьера
Сегодня порекомендую вам видео на отвлечённую тему. «4 вещи, необходимые, чтобы стать экспертом» (The 4 things it takes to be an expert). https://youtu.be/5eW6Eagr9XA
Как наш мозг распознаёт паттерны и в итоге запоминает информацию?
Когда это распознавание паттернов может быть во вред?
Достаточно ли 10000 часов, чтобы стать экспертом?
Почему в одной области эксперт может предсказать будущие события, а в другой нет?
Автор приводит данные различных исследований и несколько интересных историй.
Извините, видео на английском, но можно включить автоматически переведённые субтитры.
Сегодня порекомендую вам видео на отвлечённую тему. «4 вещи, необходимые, чтобы стать экспертом» (The 4 things it takes to be an expert). https://youtu.be/5eW6Eagr9XA
Как наш мозг распознаёт паттерны и в итоге запоминает информацию?
Когда это распознавание паттернов может быть во вред?
Достаточно ли 10000 часов, чтобы стать экспертом?
Почему в одной области эксперт может предсказать будущие события, а в другой нет?
Автор приводит данные различных исследований и несколько интересных историй.
Извините, видео на английском, но можно включить автоматически переведённые субтитры.
YouTube
The Expert Myth
Which experts have real expertise? This video is sponsored by Brilliant. The first 200 people to sign up via https://brilliant.org/veritasium get 20% off a yearly subscription.
Thanks to https://www.chess24.com/ and Chessable for the clip of Magnus.
▀▀▀…
Thanks to https://www.chess24.com/ and Chessable for the clip of Magnus.
▀▀▀…
👍6
День 1390. #ЗаметкиНаПолях #AsyncTips
Блокировки с async
Задача
Имеются общие данные. Требуется обеспечить безопасное чтение и запись этих данных из разных блоков кода, внутри которых может использоваться await.
Решение
Тип SemaphoreSlim был обновлён в .NET 4.5 для обеспечения совместимости с async. Пример использования:
В этой ситуации действуют рекомендации из предыдущего совета:
Экземпляры блокировок должны быть приватными; т.е. не должны быть доступными за пределами класса. Обязательно чётко документируйте (и тщательно продумывайте), что именно защищает экземпляр блокировки. Сведите к минимуму объём кода, выполняемого при удержании блокировки. В частности, не вызывайте произвольный код, включая выдачу событий, вызов виртуальных методов и вызов делегатов.
Источник: Стивен Клири “Конкурентность в C#”. 2-е межд. изд. — СПб.: Питер, 2020. Глава 12.
Блокировки с async
Задача
Имеются общие данные. Требуется обеспечить безопасное чтение и запись этих данных из разных блоков кода, внутри которых может использоваться await.
Решение
Тип SemaphoreSlim был обновлён в .NET 4.5 для обеспечения совместимости с async. Пример использования:
class MyClassТестовый вариант использования класса:
{
private int _value;
// Блокировка защищает поле _value
private readonly SemaphoreSlim
semaphore = new SemaphoreSlim(1);
public async Task IncAsync(string name)
{
await semaphore.WaitAsync();
try
{
int oldValue = _value;
await Task.Delay(1000 * oldValue);
_value = oldValue + 1;
Console.WriteLine($"{name}: {_value}");
}
finally
{
semaphore.Release();
}
}
}
var cls = new MyClass();Этот код будет выводить одну за другой строки с постоянно увеличивающейся задержкой между ними:
for (int i = 1; i <= 5; i++)
{
int count = i;
Thread t = new(
async () =>
await cls.IncAsync("Поток " + count)
);
t.Start();
}
Console.ReadLine();
Поток 4: 1Заметьте, что SemaphoreSlim принимает в качестве параметра конструктора количество потоков, которые одновременно могут получить доступ к блокировке. В данном случае мы задали 1.
Поток 3: 2
Поток 2: 3
Поток 5: 4
Поток 1: 5
В этой ситуации действуют рекомендации из предыдущего совета:
Экземпляры блокировок должны быть приватными; т.е. не должны быть доступными за пределами класса. Обязательно чётко документируйте (и тщательно продумывайте), что именно защищает экземпляр блокировки. Сведите к минимуму объём кода, выполняемого при удержании блокировки. В частности, не вызывайте произвольный код, включая выдачу событий, вызов виртуальных методов и вызов делегатов.
Источник: Стивен Клири “Конкурентность в C#”. 2-е межд. изд. — СПб.: Питер, 2020. Глава 12.
👍23
День 1391. #ЗаметкиНаПолях
Подробнее об Обязательных Членах Класса в C#11
В C#11 представлено новое ключевое слово required, которое может применяться к полю и свойству класса, записи или структуры.
var foo = new Foo();
мы получим ошибку CS9035: Required member 'Foo._field' must be set in the object initializer or attribute constructor. (Обязательный член 'Foo._field' должен быть задан в инициализаторе объекта или конструктор должен иметь атрибут.)
Это очень полезное дополнение для улучшения сценария инициализации объекта, особенно в отношении init-свойств, которые могут быть инициализированы только в конструкторе или в инициализаторе.
Ограничения обязательных членов
1. required не может применяться к закрытому члену, поскольку ограничение ключевого слова действует за пределами родительского класса, когда вызывающий объект создаёт его экземпляр.
2. required не может применяться к статическому члену, поскольку оно предназначено для использования только во время создания экземпляра объекта.
3. required не может применяться к члену, доступному только для чтения, который может быть назначен только в конструкторе.
Зачем это нужно?
Инициализаторы объектов были введены для преодоления некоторых известных ограничений конструктора, вроде необходимости соблюдать порядок параметров, необходимости задавать все параметры, даже которые не нужны, ломающих изменениях, когда в класс добавляется новый член и новый параметр в конструктор и т.п.
До сих пор было невозможно требовать, чтобы инициализаторы устанавливали член, что приводило к необходимости использовать конструктор в таком сценарии.
Обязательные члены и конструктор
Ключевое слово required на самом деле является частью публичного контракта всех конструкторов класса. Компилятор не пытается проверить, присваивается ли значение обязательному члену в самом конструкторе. Если это ваш случай, добавьте атрибут SetsRequiredMembers к конструктору, что сообщит компилятору, что обязательные члены заданы.
Обязательные члены и переопределение свойств
Есть несколько ограничений при переопределении обязательных свойств:
1. required нельзя использовать интерфейсах и для членов, являющихся явной реализацией интерфейса.
2. При переопределении обязательного виртуального или абстрактного свойства ключевое слово required должно быть указано повторно.
Подробнее об Обязательных Членах Класса в C#11
В C#11 представлено новое ключевое слово required, которое может применяться к полю и свойству класса, записи или структуры.
class Foo {Оно обязывает вызывающий код инициализировать поле или свойство. Если этого не сделать:
internal required int _field;
internal required int
Prop { get; set; }
}
var foo = new Foo();
мы получим ошибку CS9035: Required member 'Foo._field' must be set in the object initializer or attribute constructor. (Обязательный член 'Foo._field' должен быть задан в инициализаторе объекта или конструктор должен иметь атрибут.)
Это очень полезное дополнение для улучшения сценария инициализации объекта, особенно в отношении init-свойств, которые могут быть инициализированы только в конструкторе или в инициализаторе.
Ограничения обязательных членов
1. required не может применяться к закрытому члену, поскольку ограничение ключевого слова действует за пределами родительского класса, когда вызывающий объект создаёт его экземпляр.
2. required не может применяться к статическому члену, поскольку оно предназначено для использования только во время создания экземпляра объекта.
3. required не может применяться к члену, доступному только для чтения, который может быть назначен только в конструкторе.
Зачем это нужно?
Инициализаторы объектов были введены для преодоления некоторых известных ограничений конструктора, вроде необходимости соблюдать порядок параметров, необходимости задавать все параметры, даже которые не нужны, ломающих изменениях, когда в класс добавляется новый член и новый параметр в конструктор и т.п.
До сих пор было невозможно требовать, чтобы инициализаторы устанавливали член, что приводило к необходимости использовать конструктор в таком сценарии.
Обязательные члены и конструктор
Ключевое слово required на самом деле является частью публичного контракта всех конструкторов класса. Компилятор не пытается проверить, присваивается ли значение обязательному члену в самом конструкторе. Если это ваш случай, добавьте атрибут SetsRequiredMembers к конструктору, что сообщит компилятору, что обязательные члены заданы.
Обязательные члены и переопределение свойств
Есть несколько ограничений при переопределении обязательных свойств:
1. required нельзя использовать интерфейсах и для членов, являющихся явной реализацией интерфейса.
2. При переопределении обязательного виртуального или абстрактного свойства ключевое слово required должно быть указано повторно.
interface IInterfaceИсточник: https://blog.ndepend.com/c-11-required-members/
{
int Prop { get; init; }
// ОШИБКА
required int Foo { get; init; }
}
abstract class Base
{
public required abstract int
Abstr { get; init; }
public required virtual int
Virt { get; init; }
}
class Derived : Base, IInterface
{
public int Foo { get; init; }
// ОШИБКА
required int IInterface.Prop { get; init; }
// required повторно в переопределениях
public required override int
Abstr { get; init; }
public required override int
Virt { get; init; }
}
👍9
День 1392. #TipsAndTricks
Советы и Инструменты Отладки. Начало
В этой серии постов приведу несколько советов и инструментов, которые помогут отлаживать приложения .NET. Список не исчерпывающий, здесь только некоторые варианты.
Коротко случайные советы
- Поговорите с резиновой уточкой.
- Прогуляйтесь, поспите, поиграйте в игру и т.д., а потом вернитесь к своему коду на свежую голову.
- Внимательно прочитайте документацию.
- Прежде чем изменять код, убедитесь, что вы понимаете, почему он ведёт себя не так, как вы ожидаете.
- Напишите тест, который воспроизводит ошибку, чтобы вы могли быстро исправить её.
- Удалите/закомментируйте весь код, который не нужен для воспроизведения ошибки. В итоге у вас должен получиться небольшой фрагмент кода, воспроизводящий ошибку (используйте систему контроля версий, чтобы вы всегда могли вернуться к исходному коду).
- Можно сделать наоборот: создать новое приложение и постепенно добавлять код, пока ошибка не появится.
- Время, потраченное на использование отладчика, едва ли ускорит решение последующих задач. А вот улучшение логирования и сообщений об ошибках поможет. Это может сэкономить вам или вашим коллегам время в будущем.
А теперь более подробные советы.
1. Код выполняется?
Если нет уверенности, что код действительно выполняется, добавьте
Если вы не можете запустить процесс в режиме отладки и не можете найти способ присоединить отладчик к существующему процессу, вы можете использовать
В Windows отладку процесса можно начать из Диспетчера Задач. Нажмите правой кнопкой мыши на нужный процесс и выберите Debug (Отладка).
3. Отладка более чем одного процесса за раз
Visual Studio может отлаживать несколько процессов одновременно. Например, вы можете одновременно отлаживать веб-приложение и консольное приложение. Для этого перейдите в Debug > Set Startup Projects… (Отладка > Установить стартовые проекты) и установите на запуск несколько проектов. Кроме того, в меню Debug > Attach to Process… (Отладка > Прикрепить к процессу…) можно выбрать несколько процессов.
4. Наблюдение за значением переменной без отладчика
Если вы не можете подключить отладчик, вы можете регистрировать значения с помощью
Продолжение следует…
Источник: https://www.meziantou.net/debugging-tips-and-tools.htm
Советы и Инструменты Отладки. Начало
В этой серии постов приведу несколько советов и инструментов, которые помогут отлаживать приложения .NET. Список не исчерпывающий, здесь только некоторые варианты.
Коротко случайные советы
- Поговорите с резиновой уточкой.
- Прогуляйтесь, поспите, поиграйте в игру и т.д., а потом вернитесь к своему коду на свежую голову.
- Внимательно прочитайте документацию.
- Прежде чем изменять код, убедитесь, что вы понимаете, почему он ведёт себя не так, как вы ожидаете.
- Напишите тест, который воспроизводит ошибку, чтобы вы могли быстро исправить её.
- Удалите/закомментируйте весь код, который не нужен для воспроизведения ошибки. В итоге у вас должен получиться небольшой фрагмент кода, воспроизводящий ошибку (используйте систему контроля версий, чтобы вы всегда могли вернуться к исходному коду).
- Можно сделать наоборот: создать новое приложение и постепенно добавлять код, пока ошибка не появится.
- Время, потраченное на использование отладчика, едва ли ускорит решение последующих задач. А вот улучшение логирования и сообщений об ошибках поможет. Это может сэкономить вам или вашим коллегам время в будущем.
А теперь более подробные советы.
1. Код выполняется?
Если нет уверенности, что код действительно выполняется, добавьте
throw
или Console.Write
в код. Да, звучит банально, но отладочный вывод в некоторых случаях сделать проще всего. Для надёжности можно обернуть этот код в директивы препроцессора: public void MethodToDebug()2. Запуск отладчика из кода
{
#if DEBUG
Console.WriteLine("Debugging");
throw new Exception("Debugging");
#endif
//…
}
Если вы не можете запустить процесс в режиме отладки и не можете найти способ присоединить отладчик к существующему процессу, вы можете использовать
System.Diagnostics.Debugger.Launch()
или System.Diagnostics.Debugger.Break();
там, где вы хотите установить точку останова. См. подробнее об их использовании.В Windows отладку процесса можно начать из Диспетчера Задач. Нажмите правой кнопкой мыши на нужный процесс и выберите Debug (Отладка).
3. Отладка более чем одного процесса за раз
Visual Studio может отлаживать несколько процессов одновременно. Например, вы можете одновременно отлаживать веб-приложение и консольное приложение. Для этого перейдите в Debug > Set Startup Projects… (Отладка > Установить стартовые проекты) и установите на запуск несколько проектов. Кроме того, в меню Debug > Attach to Process… (Отладка > Прикрепить к процессу…) можно выбрать несколько процессов.
4. Наблюдение за значением переменной без отладчика
Если вы не можете подключить отладчик, вы можете регистрировать значения с помощью
Console.WriteLine()
, File.WriteAllText()
или Logger.LogDebug()
для вывода значений, которые вы хотите наблюдать.Продолжение следует…
Источник: https://www.meziantou.net/debugging-tips-and-tools.htm
👍13
День 1393. #TipsAndTricks
Советы и Инструменты Отладки. Продолжение
Начало
5. Загрузка символов сборки
Для отладки скомпилированных сборок необходимо загрузить файлы символов, сопоставляющие бинарный код со строками кода в текстовых файлах. Последние версии Visual Studio загружают символы автоматически. В более старых версиях можно пройти в Debug > Windows > Modules (Отладка > Окна > Модули), там найти модуль, который хотите отладить, и нажать Load Symbols (Загрузить символы).
Если символы найти не удаётся, возможно нужно включить (или добавить) символьные серверы. В настройках (Tools > Options…) зайдите в Debugging > Symbols (Отладка > Символы).
6. Различные виды точек останова
Есть много способов остановить выполнение кода:
- Точки останова: остановка всегда при выполнении выражения.
- Условные точки останова: остановка при выполнении выражения, когда соблюдается условие.
- Точки останова в данных: остановка, когда значение данных в памяти меняется
- Зависимые точки останова: остановка, только когда другая точка останова достигнута. Полезны в сложном сценарии, таком как отладка многопоточного приложения.
- Остановка при исключении
7. Добавление утверждений
Точки останова полезны для отладки кода, но их не всегда легко использовать. Вы можете использовать утверждения для проверки состояния вашего кода.
Продолжение следует…
Источник: https://www.meziantou.net/debugging-tips-and-tools.htm
Советы и Инструменты Отладки. Продолжение
Начало
5. Загрузка символов сборки
Для отладки скомпилированных сборок необходимо загрузить файлы символов, сопоставляющие бинарный код со строками кода в текстовых файлах. Последние версии Visual Studio загружают символы автоматически. В более старых версиях можно пройти в Debug > Windows > Modules (Отладка > Окна > Модули), там найти модуль, который хотите отладить, и нажать Load Symbols (Загрузить символы).
Если символы найти не удаётся, возможно нужно включить (или добавить) символьные серверы. В настройках (Tools > Options…) зайдите в Debugging > Symbols (Отладка > Символы).
6. Различные виды точек останова
Есть много способов остановить выполнение кода:
- Точки останова: остановка всегда при выполнении выражения.
- Условные точки останова: остановка при выполнении выражения, когда соблюдается условие.
- Точки останова в данных: остановка, когда значение данных в памяти меняется
- Зависимые точки останова: остановка, только когда другая точка останова достигнута. Полезны в сложном сценарии, таком как отладка многопоточного приложения.
- Остановка при исключении
7. Добавление утверждений
Точки останова полезны для отладки кода, но их не всегда легко использовать. Вы можете использовать утверждения для проверки состояния вашего кода.
public void MethodToDebug()Замечание: Debug.Assert доступно только при сборке в режиме отладки.
{
for (int i = 0; i < 100; i++)
{
Debug.Assert(i != 50, "i не должно быть 50");
Console.WriteLine(i);
}
}
Продолжение следует…
Источник: https://www.meziantou.net/debugging-tips-and-tools.htm
👍10
День 1394. #TipsAndTricks
Советы и Инструменты Отладки. Продолжение
Начало 1-4
Продолжение 5-7
8. Наблюдение за приложением без отладчика
Вы можете наблюдать за http-вызовами, используя прокси-сервер, такой как Fiddler.
В браузерах на движке Chromium помимо вкладки Network (Сеть) в инструментах разработчика, есть:
-
-
Также следить за сетевым трафиком можно с помощью WireShark.
Вы можете следить за файловой системой, регистром и активностью процессов/потоков с помощью procmon (Монитор Процессов) или wtrace.
Можно использовать dotnet-counter для быстрого мониторинга таких вещей, как загрузка ЦП или частота исключений, возникающих в вашем приложении .NET Core.
dotnet-trace или PerfView используются для сбора ETW-событий вашего приложения .NET Core. Это позволяет получить много информации о приложении, такой как запросы к базе данных, HTTP-вызовы, DNS-запросы, конфликты блокировок, информация о пуле потоков, сборках мусора, JIT, загрузке сборок и т.д.
Анализатор производительности Windows создаёт графики и таблицы данных для событий трассировки событий Windows (ETW).
Дамп приложения можно сделать с помощью dotnet-dump и проанализировать его позже с помощью Visual Studio. Если вам нужно создать дамп при выполнении определенных условий, вы можете попробовать ProcDump.
Handle или ProcessExplorer помогут перечислить дескрипторы (открытые файлы, ключи реестра, порты, примитивы синхронизации).
Visual Studio предоставляет множество инструментов для отладки приложения. Кроме того, вы можете использовать WinDbg и dotnet-sos. Инструменты Sysinternals также очень полезны.
Окончание следует…
Источник: https://www.meziantou.net/debugging-tips-and-tools.htm
Советы и Инструменты Отладки. Продолжение
Начало 1-4
Продолжение 5-7
8. Наблюдение за приложением без отладчика
Вы можете наблюдать за http-вызовами, используя прокси-сервер, такой как Fiddler.
В браузерах на движке Chromium помимо вкладки Network (Сеть) в инструментах разработчика, есть:
-
about://net-internals/
- различные сетевые инструменты,-
about://net-export/
- экспорт данных по сетевым соединениям.Также следить за сетевым трафиком можно с помощью WireShark.
Вы можете следить за файловой системой, регистром и активностью процессов/потоков с помощью procmon (Монитор Процессов) или wtrace.
Можно использовать dotnet-counter для быстрого мониторинга таких вещей, как загрузка ЦП или частота исключений, возникающих в вашем приложении .NET Core.
dotnet-trace или PerfView используются для сбора ETW-событий вашего приложения .NET Core. Это позволяет получить много информации о приложении, такой как запросы к базе данных, HTTP-вызовы, DNS-запросы, конфликты блокировок, информация о пуле потоков, сборках мусора, JIT, загрузке сборок и т.д.
Анализатор производительности Windows создаёт графики и таблицы данных для событий трассировки событий Windows (ETW).
Дамп приложения можно сделать с помощью dotnet-dump и проанализировать его позже с помощью Visual Studio. Если вам нужно создать дамп при выполнении определенных условий, вы можете попробовать ProcDump.
Handle или ProcessExplorer помогут перечислить дескрипторы (открытые файлы, ключи реестра, порты, примитивы синхронизации).
Visual Studio предоставляет множество инструментов для отладки приложения. Кроме того, вы можете использовать WinDbg и dotnet-sos. Инструменты Sysinternals также очень полезны.
Окончание следует…
Источник: https://www.meziantou.net/debugging-tips-and-tools.htm
👍9
День 1395. #TipsAndTricks
Советы и Инструменты Отладки. Окончание
Начало 1-4
Продолжение 5-7
Продолжение 8
9. Просмотр значений в отладчике
Окна Watch – Debug > Windows > Watch > Watch 1 (Отладка > Окна > Просмотр > Просмотр 1) позволяют оценивать несколько выражений. Все выражения пересчитываются, когда выполнение приостанавливается. Обратите внимание, что вы можете использовать такие команды, как
Идентификатор объекта (Object ID) позволяет создать глобально доступный идентификатор для объекта. Таким образом, даже если значение недоступно в текущем контексте, вы всё равно можете сослаться на значение, используя
Подсказки к данным обеспечивают удобный способ просмотра информации о переменных в вашей программе во время отладки. Наведите курсор на переменную и нажмите на значок булавки, чтоб его закрепить. Если значение изменилось с момента последней оценки, оно отображается красным цветом, поэтому вы можете быстро увидеть, что изменилось.
Пользовательские визуализаторы позволяют отображать отформатированные значения вместо необработанных. Существуют визуализаторы для строк или коллекций IEnumerable.
Окно Immediate (Debug > Windows > Immediate при отладке) позволяет в точке останова выполнять произвольный код и видеть результат.
10. Отладка многопоточных приложений
- Получение списка запущенных потоков (Debug > Windows > Threads). Вы можете дважды щелкнуть по потоку, чтобы переключиться на него.
- Получение списка задач в .NET (Debug > Windows > Tasks).
- Окно Parallel watch (Debug > Windows > Parallel Watch > Parallel Watch 1) позволяет оценить значение объекта во всех потоках.
- Окно Parallel Stacks объединяет все похожие стеки/задачи вместе и показывает количество потоков/задач, выполняющих один и тот же код. Это даст вам хорошее представление о том, что происходит в вашем приложении.
Если вы отлаживаете несколько приложений, окно «Parallel Stacks» может объединять стеки вызовов из всех запущенных процессов.
11. Другие инструменты
- Проверка используемых портов в Windows
PowerShell
PowerShell
Источник: https://www.meziantou.net/debugging-tips-and-tools.htm
Советы и Инструменты Отладки. Окончание
Начало 1-4
Продолжение 5-7
Продолжение 8
9. Просмотр значений в отладчике
Окна Watch – Debug > Windows > Watch > Watch 1 (Отладка > Окна > Просмотр > Просмотр 1) позволяют оценивать несколько выражений. Все выражения пересчитываются, когда выполнение приостанавливается. Обратите внимание, что вы можете использовать такие команды, как
nq
(без кавычек) или nse
(без побочных эффектов), h
(шестнадцатеричный). См. подробнее про форматирование выражений в отладчике.Идентификатор объекта (Object ID) позволяет создать глобально доступный идентификатор для объекта. Таким образом, даже если значение недоступно в текущем контексте, вы всё равно можете сослаться на значение, используя
$N
, где N — идентификатор объекта. См. подробнее.Подсказки к данным обеспечивают удобный способ просмотра информации о переменных в вашей программе во время отладки. Наведите курсор на переменную и нажмите на значок булавки, чтоб его закрепить. Если значение изменилось с момента последней оценки, оно отображается красным цветом, поэтому вы можете быстро увидеть, что изменилось.
Пользовательские визуализаторы позволяют отображать отформатированные значения вместо необработанных. Существуют визуализаторы для строк или коллекций IEnumerable.
Окно Immediate (Debug > Windows > Immediate при отладке) позволяет в точке останова выполнять произвольный код и видеть результат.
10. Отладка многопоточных приложений
- Получение списка запущенных потоков (Debug > Windows > Threads). Вы можете дважды щелкнуть по потоку, чтобы переключиться на него.
- Получение списка задач в .NET (Debug > Windows > Tasks).
- Окно Parallel watch (Debug > Windows > Parallel Watch > Parallel Watch 1) позволяет оценить значение объекта во всех потоках.
- Окно Parallel Stacks объединяет все похожие стеки/задачи вместе и показывает количество потоков/задач, выполняющих один и тот же код. Это даст вам хорошее представление о том, что происходит в вашем приложении.
Если вы отлаживаете несколько приложений, окно «Parallel Stacks» может объединять стеки вызовов из всех запущенных процессов.
11. Другие инструменты
- Проверка используемых портов в Windows
PowerShell
$Port = 5000- Проверка конфигурации DNS
Get-Process -Id (Get-NetTCPConnection -LocalPort $port).OwningProcess
Get-Process -Id (Get-NetUDPEndpoint -LocalPort $port).OwningProcess
netstat -a -b
PowerShell
Resolve-DnsName -Name www.google.comТакже можно использовать онлайн сервис, вроде https://dnslookup.online/.
Resolve-DnsName -Type A -Name www.google.com
Источник: https://www.meziantou.net/debugging-tips-and-tools.htm
👍6