.NET Разработчик
6.51K subscribers
427 photos
2 videos
14 files
2.04K links
Дневник сертифицированного .NET разработчика.

Для связи: @SBenzenko

Поддержать канал:
- https://boosty.to/netdeveloperdiary
- https://patreon.com/user?u=52551826
- https://pay.cloudtips.ru/p/70df3b3b
Download Telegram
Channel photo updated
День шестьсот сорок шестой. #ЧтоНовенького
.NET 5.0 запускается на .NET Conf 10-12 ноября
.NET Conf - это бесплатное трехдневное виртуальное мероприятие для разработчиков, организованное совместно сообществом .NET и Microsoft. В этом году .NET 5.0 будет запущен на .NET Conf 2020.

В течение этих трех дней будет проводиться множество сессий с участием докладчиков из сообщества и команд .NET. Присоединяйтесь к беседе и задавайте вопросы, используя хэштег: #dotNETConf в Twitter.

На конференции планируется более 80 прямых трансляций на www.dotnetconf.net, Microsoft Learn TV, YouTube канале .NET и канале Visual Studio Twitch.

Конференция начнётся 10 ноября в 8:00 по тихоокеанскому времени (19:00 по Москве) со вступительного слова от директор по управлению программами Microsoft Скотта Хантера.

Кроме того, можно посетить местные виртуальные мероприятия в вашем часовом поясе и на вашем языке.

Источник: https://devblogs.microsoft.com/dotnet/net-5-0-launches-at-net-conf-november-10-12/
День шестьсот сорок седьмой. #Юмор
Сегодня хотел выложить, наверное, самые известные из «Хроник» 2000х – «Дневник тестировщика». Но повесть не влезает даже в телеграф, поэтому вот вам ссыль на старый ламповый сайт самиздата, даже от дизайна которого сводит олдскулы.

https://samlib.ru/b/brigadir_j_a/test.shtml

Ностальгируйте, наслаждайтесь)))
День шестьсот сорок восьмой. #TipsAndTricks
Советы по работе с Windows Terminal
Windows Terminal имеет множество функций для настройки под ваши нужды.

Первый запуск
Терминал по умолчанию поставляется с профилями Windows PowerShell, командной строки и Azure Cloud Shell. Если у вас установлен какой-либо дистрибутив Windows для Linux (WSL), терминал автоматически создаст профиль для него.

Настройка
Терминал поставляется с большим набором настроек по умолчанию, включая цветовые схемы и сочетания клавиш. Если вы хотите просмотреть файл настроек по умолчанию, нажмите кнопку «Настройки» в раскрывающемся меню, удерживая Alt.
Настроить можно как отдельные профили, так и применить глобальные настройки для всех профилей, добавив параметр в массив defaults внутри объекта profiles в файле настроек. Список всех возможных настроек профиля можно найти на странице настроек профиля в документации.

Цветовые схемы
Терминал по умолчанию поставляется с набором цветовых схем. Новые можно найти на terminalplash.com. Также можно подобрать цветовую схему к фоновому изображению, используя палитру PowerToys.
Oh my Posh и Terminal-Icons позволяют настроить внешний вид строки приглашения с помощью цветов, глифов и смайликов.

wt.exe с аргументами
Вы можете запустить терминал в определенной конфигурации с помощью команды wt.exe и аргументов командной строки. Например, можно передать вид расположения вкладок и панелей, а также их начальные каталоги и профили. Можно сохранить эту команду как ярлык, чтобы открывать терминал в нужной конфигурации. А если выполнить её внутри терминала, она изменит текущее окно.

Панели
Терминал поддерживает несколько панелей. Вы можете открыть новую панель, удерживая Alt и щёлкнув на один из профилей в раскрывающемся списке, или используя сочетание клавиш: Alt+Shift+D. Перемещать фокус по панелям можно стрелками, удерживая Alt. А изменить размер панелей также стрелками, удерживая Alt+Shift.

Копирование и вставка
В Терминале по умолчанию для копирования и вставки используются сочетания клавиш Ctrl+C и Ctrl+V. Если ничего не выделено, Ctrl+C будет действовать как обычно, как команда прерывания текущей операции.

Команды по горячим клавишам
Терминал даёт возможность вставлять команды по горячим клавишам. Это можно сделать, добавив строку в массив actions файла настроек:
Например, очистка экрана:
{"command":{"action":"sendInput",
"input": "clear\r"},
"keys": "alt+k"}

Переход к родительскому каталогу:
{"command": {"action": "sendInput",
"input": "cd..\r"},
"keys": "ctrl+up"}
Также можно использовать эту функцию для запуска сборок или тестовых скриптов.

Источник: https://devblogs.microsoft.com/commandline/windows-terminal-tips-and-tricks/
День шестьсот сорок девятый. #ЗаметкиНаПолях
Жизненный цикл запроса в
ASP.NET Core MVC 3. Начало
Жизненный цикл запроса – это серия компонентов, событий или этапов приложения, которые обрабатывают запрос или отвечают на действие пользователя.

Жизненный цикл запроса в ASP.NET Core MVC представлен на рисунке ниже.
1. Промежуточное ПО (Middleware)
Приложения MVC в .NET Core построены на основе концепции промежуточного ПО. Компоненты промежуточного ПО образуют основные блоки HTTP-конвейера приложения. Они предоставляют такие функции, как возможность обслуживания статических файлов, авторизации пользователей, маршрутизации запросов и т.п.

2. Маршрутизация (Routing)
Модель MVC фактически реализуется с помощью промежуточного ПО маршрутизации. .NET Core 3 использует новую систему, называемую маршрутизацией конечных точек. Она выполняет две важные задачи:
- выбор конечной точки для обработки запроса,
- выполнение этой конечной точки.
В контексте MVC конечную точку можно рассматривать как метод действия контроллера. Таким образом выполнение конечной точки переводит запрос из промежуточного ПО в MVC.

3. Инициализация контроллера
Контроллер создаётся в фабрике контроллеров. Затем компонент, называемый инициатором действия контроллера, управляет выполнением метода действия, чтобы предоставить функции, с которыми мы знакомы в повседневной разработке, вроде привязки модели.

4. Выполнение метода действия
На этом этапе также вызываются фильтры действий и выполняется сам метод действия, который производит результат действия.

5. Выполнение результата действия
После того, как результат действия подготовлен, выполняется следующий этап - выполнение результата. MVC отделяет объявление результата от выполнения результата, чтобы обеспечить большую гибкость абстракции. Кроме того, на этом этапе выполняются фильтры результатов действия.

6. Отображение представления
Если результатом является тип представления, вызывается механизм представления, который отвечает за поиск и отображение представления (генерация ответа HTTP). В противном случае итогом выполнения результата действия является вывод результата в ответ HTTP напрямую.

Продолжение следует…

Источник:
https://app.pluralsight.com/library/courses/aspnet-core-3-mvc-request-life-cycle/
День шестьсот пятидесятый. #ЗаметкиНаПолях
Жизненный цикл запроса в
ASP.NET Core MVC 3. Продолжение
Начало

Промежуточное ПО (Middleware)
Промежуточное ПО - это набор компонентов, которые образуют конвейер запросов уровня приложения. Эти компоненты отвечают за обработку входящих запросов и генерацию соответствующего ответа либо напрямую, либо с помощью инфраструктуры, такой как MVC. Промежуточное ПО обеспечивает все виды базовой инфраструктуры: маршрутизация, сессии, CORS, аутентификация, кеширование и т.п. Общие функции, которые применяются в различных приложениях, часто являются хорошими кандидатами для промежуточного ПО. Конвейер запросов .NET Core может иметь переменное количество компонентов промежуточного ПО.
Каждый модуль промежуточного ПО может воздействовать на запрос по мере его прохождения по конвейеру, а затем воздействовать снова при отправке сгенерированного ответа. Можно добавить сколько угодно компонентов промежуточного ПО, но важен порядок их регистрации.

Компоненты промежуточного ПО могут выбрать один из трёх методов обработки запроса:
1. Сгенерировать ответ (метод Run)
В этом случае конвейер запроса прерывается, ответ возвращается пользователю, а компоненты промежуточного ПО, зарегистрированные после текущего, не выполняются. Например, промежуточное ПО статических файлов возвращает содержимое файла сразу в ответ.
2. Воздействовать на запрос и передать его дальше (метод Use)
Промежуточное ПО выполняет некоторую работу (или не выполняет никакой) и передаёт запрос следующему зарегистрированному промежуточному ПО. Например, добавление записи о запросе в лог.
3. Перенаправить запрос (метод Map)
Это разновидность условного оператора в конвейере запросов. В зависимости запрошенного URL, может выполняться то или иное действие.

На картинке ниже представлена схема конвейера промежуточного ПО.
При старте приложения в классах Program.cs и Startup.cs происходит построение конвейера для обработки входящих запросов. Для примера предположим, у нас есть промежуточное ПО
- обслуживания статических файлов,
- маршрутизации,
- авторизации.

В .NET Core 3 маршрутизация разделена на два компонента:
- промежуточное ПО маршрутизации конечных точек (Endpoint Routing Middleware), которое решает, какая из зарегистрированных конечных точек должна обрабатывать запрос.
- промежуточное ПО конечных точек (Endpoint Middleware), которое выполняет конечную точку (передаёт запрос в среду MVC).
Между ними расположено промежуточное ПО авторизации, которое решает, должен ли пользователь быть авторизован для выполнения этой выбранной конечной точки. Если пользователь авторизован, запрос пересылается промежуточному ПО конечной точки.

MVC генерирует ответ определённого типа, например представление или JSON. Затем все компоненты промежуточного ПО могут, при желании, выполнить код в обратном порядке, когда ответ отправляется обратно в браузер, хотя большинство из них на этом этапе просто пропускают ответ дальше. Этот процесс выполняется для каждого запроса.

Продолжение следует…

Источник:
https://app.pluralsight.com/library/courses/aspnet-core-3-mvc-request-life-cycle/
День шестьсот пятьдесят первый. #ЗаметкиНаПолях
Жизненный цикл запроса в
ASP.NET Core MVC 3. Продолжение
Начало
Промежуточное ПО

Маршрутизация (Routing)
Маршрутизация в ASP.NET Core MVC 3 - это процесс сопоставления входящих запросов с конечными точками.
В MVC доступны два вида маршрутизации:
- традиционная маршрутизация объявляется централизованно для всего приложения,
- маршрутизация на основе атрибутов применяется непосредственно к конкретному контроллеру или методу действия через атрибут. Подробнее тут

.NET Core 3 использует новую систему маршрутизации конечных точек, которая впервые появилась в .NET Core 2.2, и обеспечивает большую гибкость в обработке запросов. В более ранних версиях был компонент промежуточного ПО, называемый маршрутизатором (см. картинку ниже). Он передавал запрос и данные в компонент MVC, называемый обработчиком маршрута. Обработчик использовал эти данные, чтобы решить, какой метод действия контроллера должен обрабатывать запрос. Затем маршрутизатор выполнял выбранный метод действия.

Это приводило к нескольким проблемам:
1. Ни один из других компонентов промежуточного ПО не знал, какая конечная точка или метод действия будет обрабатывать запрос до того, как он будет обработан MVC. Это создавало трудности для компонентов промежуточного ПО, которые должны анализировать маршруты, например, компонентов авторизации.
2. Этот рабочий процесс также тесно связывал MVC с обязанностями по маршрутизации, вместо того, чтобы отвечать только за генерацию ответа.

Маршрутизация конечных точек устраняет обе эти проблемы, абстрагируя маршрутизацию от MVC (см. картинку ниже). В ней задействованы два компонента промежуточного ПО. Их названия могут немного сбивать с толку:
1. Промежуточное ПО маршрутизации конечных точек - решает, какая конечная точка, зарегистрированная в приложении, должна обрабатывать входящий запрос. Выбранная конечная точка затем назначается объекту запроса, чтобы следующее промежуточное ПО могло использовать её данные для принятия собственных решений.
2. Промежуточное ПО конечных точек - фактически выполняет выбранную конечную точку для генерации ответа позже в конвейере.

Конечные точки - это классы, содержащие имя конечной точки, паттерн пути, метаданные и делегат запроса, который представляет собой функцию, используемую для генерации ответа на входящий запрос. В контексте MVC делегат представляет собой оболочку вокруг метода, который создаёт экземпляр контроллера и выполняет выбранный метод действия. Конечные точки создаются при старте приложения классом, который называется источник данных конечных точек методов действия контроллеров (Controller Action Endpoint Data Source). Он обходит все контроллеры и составляет список всех возможных конечных точек. Также он хранит коллекцию зарегистрированных маршрутов и может сопоставлять маршруты с конечными точками.

Продолжение следует…

Источник:
https://app.pluralsight.com/library/courses/aspnet-core-3-mvc-request-life-cycle/
День шестьсот пятьдесят второй. #ЗаметкиНаПолях
Жизненный цикл запроса в
ASP.NET Core MVC 3. Продолжение
Начало
Промежуточное ПО
Маршрутизация

Инициализация контроллера
Наконец запрос попадает во фреймворк MVC. Здесь под фреймворком понимается набор контроллеров с методами действий, фильтров и представлений Razor.
Для начала рассмотрим два важных класса.

Первый называется инициатором действий контроллера (Controller Action Invoker) и наследуется от второго абстрактного класса – инициатора ресурсов (Resource Invoker). Эти классы управляют конвейером MVC (см. картинку ниже). Делегат запроса в промежуточном ПО конечных точек передаёт данные контекста HTTP-запроса и выбранного метода действия в инициатор действий контроллера и его родительский класс. Логика инициатора ресурсов сначала выполняет фильтры авторизации, ресурсов и промежуточного ПО, чтобы понять, нужно ли вообще создавать контроллер. Если нужно, фабрика контроллеров, использует контекстные данные, предоставленные вызывающей стороной, для создания экземпляра контроллера. Затем инициируется поток исполнения соответствующего метода действия этого экземпляра контроллера. Когда метод действия возвращает результат, инициатор ресурсов выполняет результат для генерации ответа.

Фильтры
Фильтры - позволяют внедрять пользовательский код на различных этапах жизненного цикла запроса. MVC «из коробки» включает несколько встроенных фильтров, но мы также можем легко написать свои. Выполнение фильтров управляется инициатором действий контроллера, который вставляет их код в различные этапы конвейера MVC. Их место в жизненном цикле запроса определяется их типом:
1. Фильтры авторизации, ресурсов и промежуточного ПО выполняются перед созданием контроллера. То есть эти фильтры могут решить, должен ли запрос отправляться дальше по конвейеру или его следует прервать (например, при неудачной авторизации).
2. Фильтры действий и результатов действий запускаются до и после выполнения метода действия и результата соответственно.
3. Фильтры исключений могут выполняться в любом месте конвейера.

Фильтры постоянно добавлялись в MVC с ранних версий, поэтому в .NET Core 3 их довольно много. С фильтрами авторизации, действий и исключений всё более-менее понятно. Рассмотрим подробнее редко используемые фильтры ресурсов и промежуточного ПО.

Фильтры ресурсов реализуют интерфейс IResourceFilter, определяющий два метода OnResourceExecuting и OnResourceExecuted. Фильтры ресурсов уникальны тем, что они оборачивают выполнение большей части конвейера MVC. Это первое место для внедрения пользовательской логики после авторизации (OnResourceExecuting) и последнее место перед тем, как MVC вернёт ответ (OnResourceExecuted). В некотором смысле фильтры ресурсов похожи на промежуточное ПО внутри конвейера MVC. С их помощью можно выполнять кэширование или управлять поведением привязки модели.

Фильтры промежуточного ПО позволяют запускать стандартные компоненты промежуточного ПО внутри конвейера MVC. Есть две основные причины их использования:
- повторное использование логики компонента промежуточного ПО;
- предоставление компоненту промежуточного ПО большего объёма данных контекста изнутри MVC, чем это возможно на этапе выполнения промежуточного ПО.
Фильтры промежуточного ПО выполняются после фильтров авторизации, но на той же общей стадии, что и фильтры ресурсов.

Продолжение следует…

Источник:
https://app.pluralsight.com/library/courses/aspnet-core-3-mvc-request-life-cycle/
👍1
День шестьсот пятьдесят третий. #ЗаметкиНаПолях
Жизненный цикл запроса в
ASP.NET Core MVC 3. Продолжение
Начало
Промежуточное ПО
Маршрутизация
Инициализация контроллера

Выполнение метода действия
Метод действия - это любой открытый метод контроллера, который действует как конечная точка обработки входящего запроса. Выполнение метода действия управляется инициатором действий контроллера. Перед выполнением метода действия выполняется привязка модели и фильтры действий, которые могут выполняться как до, так и после метода действия. Сам метод действия создает объект результата. Методы действий не генерируют напрямую ответ для браузера. Они отвечают за предоставление данных ответа и типа ответа. Ответственность за фактическую визуализацию этих данных ответа вынесена в объекты результата действия.

Привязка модели
Привязка модели - это процесс сопоставления данных входящего запроса с параметрами метода действия. Привязка модели использует данные из различных источников HTTP-запроса, таких как URL-адрес, данные формы, заголовки и т.д. Методы действия могут требовать в качестве параметров сложный тип или несколько простых типов. Параметры метода действия также могут влиять на то, какой метод выбирается для обработки запроса.

Процессом привязки модели изнутри управляют три компонента:
1. Провайдеры связывателей моделей (model binder providers) - решают, какой связыватель модели следует использовать для параметров выбранного метода действия.
2. Связыватель модели (model binder) - выполняет работу по заполнению параметров значениями. Существуют разные типы связывателей и провайдеров связывателей для обработки различных типов данных.
3. Провайдеры значений (value providers) - извлекают данные из входящего запроса и передают их связывателю модели во время процесса привязки.

Допустим, у нас есть входящий запрос на обновление продукта, который достигает стадии привязки модели (см. картинку ниже). Инициатор действий контроллера использует фабрику связывателей модели, которая последовательно перебирает все провайдеры связывателей модели, зарегистрированные в приложении. Каждый из этих провайдеров работает с разными типами данных, поэтому каждый проверяет, может ли он предоставить связыватель для заполнения параметров методов действия. В нашем случае встроенный провайдер сложных типов (Complex Provider), создаст связыватель для обработки сложного параметра типа Product. Стоит отметить, что используется первый же провайдер, который сможет предоставить связыватель. Затем связыватель сложных моделей (Complex Model Binder) использует доступные провайдеры значений для извлечения данных из запроса и создания экземпляра типа Product. Он также выполняет валидацию модели, чтобы убедиться, что значения приемлемы и соответствуют атрибутам валидации. После того, как параметры заполнены, они передаются методу действия.

Кроме того, существует два типа компонентов, которые могут предоставлять значения:
1. Провайдеры значений (value providers) предоставляют структурированные данные в виде пар ключ-значение из таких источников, как URL-адрес и данные формы.
2. Средства форматирования ввода (input formatters) обрабатывают более сложные данные тела запроса в стандартных форматах, таких как JSON или XML.

В зависимости от конфигурации приложения и метода действия процесс привязки модели может немного отличаться от приведённого. Также стоит отметить, что, хотя описанный процесс точен концептуально, фактический код не повторяет его дословно. Связывание модели - сложная система. MVC создаёт и кэширует множество различных внутренних компонентов в зависимости от варианта использования.

Продолжение следует…

Источник:
https://app.pluralsight.com/library/courses/aspnet-core-3-mvc-request-life-cycle/
День шестьсот пятьдесят четвёртый. #Оффтоп
Отвлечёмся ненадолго от жизненного цикла запроса в ASP.NET Core. Вчера в нашем чате завязалась дискуссия про базы данных, прелести и недостатки SQL и хранимых процедур. Вот решил вам на выходные дать задачку из собственной практики. Можно рассматривать её как из цикла #ЗадачиНаСобеседовании.

Допустим, у нас есть интернет-магазин (или любой аналогичный каталог товаров и их производителей/поставщиков, скажем, Алиэкспресс). Количество товаров очень большое. Пользователь ищет товар по названию или по категории, и ему выдаётся некоторый набор товаров с их характеристиками и производителем/поставщиком. Предположим для простоты, что из-за большого количества товаров, вся информация в рамках одного поискового запроса собирается в хранимой процедуре и кэшируется во временную таблицу в БД. То есть, если пользователь изменил сортировку или фильтры в текущем поиске, нам не нужно каждый раз извлекать данные из нескольких таблиц, все они уже кэшированы.

Пользователю нужно выдать только определённое количество результатов (разбив на страницы или просто выдавать только ТопХХХ). Пользователь может сортировать результаты (по цене, релевантности, рейтингу и т.п.), применять фильтры или переходить по страницам. Все эти запросы в рамках одного поискового запроса идут к временной таблице, которая создана ранее.

Теперь собственно задача. Производители хотят знать, сколько раз, по каким поисковым запросам и с какими товарами они появлялись на страницах сайта. То есть, если был запрос на «смартфон», который вернул 20000 результатов во временную таблицу, пользователю из них показали 1000 на первой странице и 1000 на второй, а дальше он смотреть не стал. Нам нужно сохранить для статистики данные только тех производителей, которые реально были показаны пользователю (попали в 2000 из 20000). (Да, я специально взял большие числа, а не стандартные 10 на страницу, потому что с 10 товарами решение вполне очевидно и не затратно).

Вопрос: как вы это реализуете? Оцените преимущества и недостатки каждого варианта.

Поскольку я сам с этим столкнулся, мне будет очень интересно узнать ваши версии в комментариях. Как такового правильного ответа тут, наверное, нет.

Жду ваших комментариев. Свою реализацию тоже опишу в комментариях позже.
День шестьсот пятьдесят пятый. #ЗаметкиНаПолях
Жизненный цикл запроса в
ASP.NET Core MVC 3. Окончание
Начало
Промежуточное ПО
Маршрутизация
Инициализация контроллера
Выполнение метода действия

Выполнение результата действия и Отображение представления
Результаты действий отвечают за отображение результата метода действия в ответ, отправляемый клиенту. Результаты действий реализуют интерфейс IActionResult, который определяет метод ExecuteResultAsync, принимающий контекст действия (ActionContext). Этот метод реализуется различными типами результатов действий для отображения различных типов ответов. Допустим, у нас есть метод действия, отвечающий за отправку сообщения «Hello world» клиенту. Метод действия может представить результат по-разному, например:
- ContentResult выведет просто строку "Hello world",
- JsonResult выведет JSON {result: "Hello world"},
- ViewResult выведет HTML страницу с разметкой из соответствующего представления,
- FileResult выведет файл.
Выбрать тип результата можно с помощью вспомогательных методов контроллера, например:
- return View("Hello world") для ViewResult,
- return Content("Hello world") для ContentResult, и т.п.

Отображение представления
Отображение представлений в MVC управляется механизмом представлений Razor (View Engine), который отвечает за поиск и отрисовку представлений, выбранных методами действий. Существует три основных класса управляющих этим процессом:
1. View Engine - управляет процессом поиска представления. Класс реализует IViewEngine, определяющий два метода: GetView и FindView. GetView вызывается первым и пытается найти представление, используя его имя прямой путь к нему. Если представление не найдено, вызывается метод FindView, который использует дополнительную информацию из контекста метода действия.

2. View Engine Result - содержит свойства, представляющие результаты поиска представления:
- IEnumerable<string> SearchedLocations – места, где производился поиск,
- bool Success – успешность поиска,
- IView View – экземпляр найденного представления,
- string ViewName – имя представления.
Соответствующие свойства заполняются двумя методами класса:
- Found() – вызывается при обнаружении представления,
- NotFound() – если представление не найдено.

3. View - фактически отображает разметку Razor и HTML, а также любые данные, предоставленные методом действия. Класс реализует IView, определяющий свойство Path (путь к представлению) и метод визуализации представления RenderAsync. RenderAsync используется MVC для фактического создания ответа, который отправляется клиенту. Разметка Razor и код HTML конвертируются в класс C#, содержащий метод ExecuteAsync (о нём ниже).

Процесс визуализации представления в MVC начинается с вызова вспомогательного метода представления в методе действия контроллера (см. рисунок ниже). За кулисами этот метод генерирует экземпляр ViewResult, который будет выполнен инициатором ресурсов, как и любой другой результат действия. ViewResult просит у механизма представлений Razor найти представление. Механизм возвращает экземпляр класса View Engine Result. Если представление было найдено, экземпляр содержит обнаруженное представление. В противном случае предоставляется список мест, где осуществлялся поиск. Если представление было найдено, вызывается метод ExecuteAsync класса View для отображения ответа на запрос.

Источник: https://app.pluralsight.com/library/courses/aspnet-core-3-mvc-request-life-cycle/
.NET Разработчик pinned «День шестьсот пятьдесят четвёртый. #Оффтоп Отвлечёмся ненадолго от жизненного цикла запроса в ASP.NET Core. Вчера в нашем чате завязалась дискуссия про базы данных, прелести и недостатки SQL и хранимых процедур. Вот решил вам на выходные дать задачку из собственной…»
День шестьсот пятьдесят шестой. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
66. Архитектура не Завершена без Документации
Создание хорошей архитектуры - только половина дела. Необходимо описать её для всех, кто будет её использовать: инженерам, тестировщикам, владельцам продукта, аналитикам и менеджерам.

Стоит потратить время на чёткое документирование архитектуры, так как это может упростить разработку. Документация даёт всем понимание, как будет работать система, определяет общий язык, упрощает обучение новичков. Но как должна выглядеть документация, как сделать её полезной и избежать превращения документирования в обузу?

1. Ориентируйтесь на аудиторию, а не на методологию
Основной целью документации является обмен информацией, а значит любая документация должна быть написана для целевой аудитории – её читателей. Представлений архитектуры очень много: от неформальных прямоугольников и стрелок до UML или Archimate. Правильный формат может оказаться сложной задачей, особенно если вы ориентируетесь на нетехническую аудиторию.

2. Учитывайте разные взгляды
Вы вряд ли найдёте универсальный подход к документации. Разным аудиториям потребуются разные взгляды на архитектуру. План архитектуры для разработчиков будет отличаться от более абстрактного представления для менеджеров. Это хорошо. Предоставление описаний одной и той же архитектуры с разных сторон может стать проверкой прочности вашего дизайна.

3. Определите общий язык
Каждая система содержит свои абстракции, шаблоны и термины. Этот общий язык должен быть где-то чётко определён, иначе каждая аудитория начнёт придумывать свои противоречащие остальным определения.

4. Краткость – сестра таланта
Способность выражать сложные проекты в простой и доступной форме чрезвычайно важна. Длинные сложные документы могут быть пугающими и содержать неактуальный материал, затрудняющий понимание. Стремитесь к тому, чтобы документации было ровно столько, сколько нужно. Если вы не можете описать систему ясно и кратко, вы либо слишком усложняете решение, либо не понимаете его полностью. Отбрасывайте несущественные детали. Архитектурная документация должна объяснять основные концепции и шаблоны, лежащие в основе проекта, а не представлять собой сборник деталей реализации.

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

6. Создайте централизованный репозиторий
Архитектурная документация должна быть легко доступной для широкой аудитории. Подойдет простая вики, желательно с возможностью поиска, управлением версиями и комментариями. Также кто-то должен взять на себя ответственность за организацию структуры, удаление оставленных черновиков и обновление контента. Неформальные договорённости о поддержке актуальности документации обычно приводят к хаосу.

7. Стремитесь к независимой оценке документации
Документация также допускает обзоры, как и код. Рецензирование должно быть совместным процессом. Есть соблазн держать идеи при себе, пока вы не доведёте их до ума. Но чтобы по-настоящему оценить их состоятельность, требуется немного смелости. Нужно опубликовать черновики и ждать отзывов. Это поможет привлечь людей, а также упростит изменение курса разработки, если это необходимо.

Источник: https://www.ben-morris.com/architecture-without-documentation-is-incomplete/
День шестьсот пятьдесят седьмой. #ЧтоНовенького
Новый Опыт Работы с Git в Visual Studio
Git стал встроенной системой контроля версий в Visual Studio 2019, начиная с версии 16.8. Вот некоторые нововведения, которые помогут упростить работу с Git в Visual Studio.

Создание репозитория
Чтобы начать работу с Git, Visual Studio позволяет вам одним щелчком мыши добавить локальный код в Git и GitHub. Диалоговое окно «Создание репозитория Git» (см. картинку 1 ниже) содержит новый интегрированный процесс входа в GitHub, аналогичный тому, что существует для учётных записей Microsoft. Вы можете сделать репозиторий общедоступным или приватным. Также вы можете создать локальный репозиторий или отправить свой код в существующий удаленный репозиторий в Azure DevOps или у любого другого поставщика.

Меню Git верхнего уровня
Теперь вы можете получить доступ к функциям Git, используя меню Git верхнего уровня, либо по Alt+G. Здесь также есть подменю Локальные репозитории (Local Repositories), с помощью которого вы можете легко переключаться между локальными репозиториями Git, которые вы ранее открывали в Visual Studio.

Просмотр файлов в Проводнике Решения
После того, как вы открыли или клонировали репозиторий, Visual Studio поможет вам сразу перейти к вашему коду. Проводник решения загружает корень репозитория и просматривает каталог на наличие нужных файлов. Visual Studio автоматически найдёт и загрузит решение из файла .sln. Если файлов .sln несколько, вам будет предложен список доступных решений на выбор. Впоследствии вы можете переключаться между текущим открытым решением и списком решений с помощью кнопки «Переключить представление» (Switch Views) на панели инструментов проводника решений (см. картинку 2 ниже).

Оптимизировано окно Git Changes
Новое окно Git Changes предназначено для обеспечения быстрого доступа к часто используемым операциям Git. Вы можете создавать новые ветки, выполнять stash, stage, вносить правки и фиксировать изменения в одном месте, не теряя контекста. В верхней части окна кнопки fetch, pull и push позволяют синхронизировать коммиты и теги с удалёнными репозиториями. В окне Git Changes также есть индикатор, отображающий количество исходящих и входящих коммитов. Он работает как ссылка для перехода в окно репозитория Git. Оттуда вы можете просмотреть сводку исходящих и входящих коммитов перед синхронизацией (см. картинку 3 ниже).

Окно репозитория Git
Окно репозитория Git позволяет легко визуализировать всю историю вашего репозитория. Вы можете щёлкнуть правой кнопкой мыши по ветке, чтобы выполнить различные операции над ревизиями (см. картинку 4 ниже).

Улучшено разрешение конфликтов
В окне Git Changes перечислены неподтверждённые или неслитые изменения. Золотистая панель в конфликтующем файле предлагает вам открыть Редактор Слияния (Merge Editor). Три панели редактора помогут вам визуально разрешить каждый конфликт в файле. Вы также можете принять локальные или входящие изменения одним щелчком мыши (см. картинку 5 ниже).

Источник: https://devblogs.microsoft.com/visualstudio/announcing-the-release-of-the-git-experience-in-visual-studio/