.NET Разработчик
6.5K 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
День семьсот сорок второй. #ЗаметкиНаПолях #Blazor
10 Функций Blazor, о Которых Вы Вероятно не Знали. Продолжение
Начало

3. Объединение MVC и Blazor в одном проекте
Есть ли способ использовать MVC и Blazor (на стороне клиента) в одном проекте?

Если вы уже работаете над приложением ASP.NET Core MVC или Razor Pages, вы всё равно можете использовать Blazor. Поскольку Blazor является частью ASP.NET Core, он довольно хорошо интегрируется с существующими приложениями. Он может как предоставить путь миграции к Blazor, так и просто добавить дополнительную гибкость вашей кодовой базе. Чтобы использовать эту функцию воспользуйтесь тег-хелпером component для рендеринга желаемого компонента в приложении MVC:
<component type="typeof(MyComponent)" render-mode="ServerPrerendered" param-Name="Value" />
В этом видео обсуждается тег-хелпер component и использование его с Blazor.

Пре-рендеринг и аутентификация
Вы можете использовать Blazor не только в приложении MVC или Razor Pages, но для серверного пре-рендеринга, а также аутентификации через Microsoft Identity. При использовании Blazor Server или Blazor WebAssembly с включенным пре-рендерингом приложение будет использовать страницы Blazor для начальной загрузки приложения. В типичном приложении Blazor Server файл _host.cshtml инициализирует клиента Blazor с помощью тег-хелпера component:
<component type="typeof(App)" render-mode="ServerPrerendered" />
Также страницы аутентификации Identity пишутся в cshtml и генерируются на сервере даже в приложении Blazor.

4. SignalR без JavaScript
Когда Blazor был впервые выпущен, SignalR можно было использовать только через библиотеки JavaScript. Теперь у Blazor есть пакет NuGet, который включает SignalR без использования JavaScript. Пакет Microsoft.AspNetCore.SignalR.Client - это всё, что вам нужно для подключения приложения Blazor к хабу SignalR, и самое главное, вы можете сделать всё это на C#. С помощью класса SignalR HubConnection приложение Blazor может подключаться к хабу, отправлять и получать команды:
// создание подключения
var hubConnection = new HubConnectionBuilder()
.WithUrl(NavigationManager.ToAbsoluteUri("/chathub"))
.Build();

// запуск
await hubConnection.StartAsync();
// действие при получении команды
hubConnection.On<string, string>(
"ReceiveMessage", (user, message) => {
var encodedMsg = $"{user}: {message}";
messages.Add(new Message
{ Text = encodedMsg });
});

// вызываем хаб
Task Send() => hubConnection
.SendAsync("SendMessage",
userInput, messageInput);

С помощью всего нескольких строк кода можно создать приложение чата в реальном времени с использованием ASP.NET Core и Blazor WebAssembly.

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

Источник:
https://www.telerik.com/blogs/10-blazor-features-you-probably-didnt-know
День семьсот сорок третий. #Оффтоп #Курсы
Сегодня расскажу паре предстоящих онлайн конференций в рамках Microsoft Azure Virtual Training Day.

1. DevOps with GitHub
Четверг, 18 февраля 2021 с 12:00 до 14:55 по Москве
Пятница, 19 февраля 2021 с 12:00 до 14:10 по Москве
Язык: английский, доступны русские субтитры

Бесплатный вебинар, предназначенный для разработчиков и ИТ-специалистов. На нём вы узнайте, как использовать GitHub для управления рабочими процессами и сокращения времени цикла разработки, как добавлять элементы управления качеством и безопасностью в процесс сборки, а также как улучшить уведомления для обеспечения согласованной и повторяемой автоматизированной сборки и релиза.

Темы вебинара:
- Использование GitHub для улучшения совместной работы и производительности команды.
- Интеграция средств контроля безопасности и качества в процессы автоматизации, конвейеры CI/CD и среду выполнения.
- Внедрение передовых методов для помощи удалённым командам разработчиков в повышении отказоустойчивости ПО.

2. Modernize .NET Apps
Вторник, 23 февраля 2021 с 21:00 до 00:00 по Москве
Среда, 24 февраля 2021 с 21:00 до 23:15 по Москве
Язык: английский

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

Темы вебинара:
- Оценка вариантов миграции в облако.
- Перенос приложений .NET и действующих баз данных, поддерживающих эти приложения.
- Мониторинг работоспособности и производительности перенесенных приложений в Azure.

Зарегистрироваться на вебинары можно по соответствующим ссылкам.

PS: Ну и вдруг кому будет интересно.

3. Machine Learning
С 12 апреля 2021 по 20 июня 2021.
Язык: английский
Онлайн курс от Стенфордского университета. В этом курсе представлены учебные видеоролики и задания, адаптированные из курса для выпускников специальности CS229, проведенного в кампусе Стэнфорда осенью 2018 года и осенью 2019 года. Темы курса:
- Линейная и логистическая регрессия,
- Обобщённые линейные модели (GLM),
- Гауссовский дискриминантный анализ (GDA),
- Нейронные сети,
- Максимизация ожидания и т.п.

По завершении этого курса вы получите Сертификат о прохождении курса Машинного Обучения от Стэнфордского центра профессионального развития.

Очень круто! Пара незначительных нюансов:
- преподавание и задания ведутся на Python (но до апреля есть время подучить),
- 10-недельный курс стоит $1595.
День семьсот сорок четвёртый. #ЗаметкиНаПолях #Blazor
10 Функций Blazor, о Которых Вы Вероятно не Знали. Продолжение
Начало 1-2
Продолжение 3-4

5. gRPC и Protobuf
.NET полностью поддерживает gRPC, современную высокопроизводительную среду для удалённого вызова процедур с открытым исходным кодом. С выпуском .NET 5.0 и ASP.NET Core, и Blazor получили интегрированную поддержку gRPC. Поддержка включает библиотеку для создания сервера gRPC в ASP.NET и клиента gRPC в Blazor WebAssembly. Приложения gRPC обмениваются данными между клиентом и службой через бинарный канал. Инструментарий автоматически генерирует частичные классы .NET из файлов protobuf (.proto), которые представляют конкретных клиентов и службы (см. рисунок ниже). Использование частичных классов помогает разработчикам легко их расширять при необходимости.

Клиент gRPC создаётся с использованием канала, который представляет собой долгоживущее соединение с сервисом gRPC. Канал разрешается посредством внедрения зависимостей с использованием объекта GrpcChannel.
@inject GrpcChannel Channel
<SampleGrid Data="forecasts" AutoGenerateColumns="true"></SampleGrid>

@code {
private IList<WeatherForecast>? forecasts;
protected override async Task
OnInitializedAsync() {
// Создаём клиента канала
var client = new WeatherForecasts
.WeatherForecastsClient(Channel);

// Вызываем метод GetWeatherForecast
var emptyRequest = new Google
.Protobuf.WellKnownTypes.Empty();
var response = await client
.GetWeatherForecastsAsync(emptyRequest);
forecasts = response.Forecasts;
}
}
Этот новый протокол позволяет разработчикам выбирать между REST API c JSON, веб-сокетами с SignalR и передачей двоичных данных с использованием gRPC.

6. Используйте уже существующие библиотеки .NET
Есть большая вероятность, что существующий код .NET будет работать в Blazor без каких-либо изменений. Поскольку Blazor выполняет стандартный код .NET, это означает, что ваше приложение может использовать библиотеки DLL .NET и пакеты NuGet, которые были написаны до выпуска Blazor. Библиотеки, которые поддерживают .NET Standard или .NET Core и не ориентированы на API-интерфейсы конкретной платформы (например, Xamarin или Desktop), скорее всего, будут работать и в Blazor. Вот несколько отличных примеров библиотек:
- Markdig для преобразования строк markdown-разметки в HTML,
- FluentValidation для создания правил проверки на уровне приложения.

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

Источник:
https://www.telerik.com/blogs/10-blazor-features-you-probably-didnt-know
День семьсот сорок пятый. #Оффтоп
Фарша вам в ленту. Вчера у АйТиБороды вышло интервью с Chief Software Engineer из EPAM Сергеем Тихоном. Функциональщина, F#, ML, Akka, Blazor, акторы, вот это всё. Если интересно, выделите 3 часа, устройтесь по удобнее и приятного просмотра.
https://youtu.be/t7iP7AVRNnI
День семьсот сорок шестой. #ЗаметкиНаПолях #Blazor
10 Функций Blazor, о Которых Вы Вероятно не Знали. Продолжение
Начало 1-2
Продолжение 3-4
Продолжение 5-6

7. Библиотеки классов Razor: маршрутизация и сервисы
В Blazor не только легко использовать общий код с библиотеками классов .NET, но также легко использовать общие компоненты Razor и веб-ресурсы с помощью библиотек классов Razor. Библиотеки классов Razor (RCL) могут включать CSS, JavaScript, статические файлы, такие как изображения, а также компоненты. Компоненты в RCL могут содержать директивы маршрута, и эти маршруты легко добавляются в любое приложение Blazor, которое хочет их использовать.

Настройка общей маршрутизации
В корневом компоненте приложения Blazor, App.razor, маршрутизация настраивается при помощи компонента Router. Компонент Router имеет необязательный параметр AdditionalAssemblies, который используется для поиска маршрутов из других сборок. Просто укажите сборку, и Blazor найдёт любые маршруты и добавит их в приложение. Повторяющиеся маршруты вызовут ошибку компилятора, поэтому используйте их с осторожностью.
<Router
AppAssembly="@typeof(Program).Assembly"
AdditionalAssemblies="new[]
{ typeof(MyComponent).Assembly }">
...
</Router>

Сервисные интерфейсы для библиотек классов Razor
Компоненты в RCL также могут использовать интерфейсы для совместного использования сервисов. В зависимости от типа проекта Blazor, приложения могут запускаться на стороне клиента в WebAssembly или на сервере. Основное различие между компонентами, работающими в WebAssembly, и на стороне сервера заключается в том, как они получают данные. WebAssembly-приложению потребуется HTTP-запрос для получения данных, а серверное приложение может взаимодействовать со службами напрямую без HTTP.
На рисунке ниже мы видим схему того, как два приложения могут использовать общий компонент при делегировании сервиса данных через интерфейс.

8. Полноценное тестирование и контроль качества
Blazor - это новый фреймворк для веб-приложений, который обещает предоставить нативные возможности веб-клиента без необходимости написания кода JavaScript. Разработчики могут легко создавать полнофункциональные веб-приложения с помощью платформы и инструментов .NET. Многие выделяют этот упор на .NET как сильную сторону Blazor, однако наибольший потенциал у Blazor может быть в тестировании.
Два распространенных подхода к тестированию компонентов Blazor — это сквозное (end-to-end, E2E) и модульное тестирование:
1. Модульные тесты пишутся с помощью библиотеки модульного тестирования, и покрывают:
- рендеринг компонентов,
- проверку вывода и состояния компонентов,
- запуск обработчиков событий и методов жизненного цикла,
- утверждения, что поведение компонента правильное.
bUnit - пример библиотеки, которая позволяет выполнять модульное тестирование компонентов Razor.

2. При E2E тестировании средство выполнения тестов запускает приложение Blazor и проверяет тестируемую систему, взаимодействуя с ней через браузер. Selenium - пример среды тестирования E2E, которую можно использовать с приложениями Blazor.

Окончание следует…

Источники:
-
https://www.telerik.com/blogs/10-blazor-features-you-probably-didnt-know
-
https://docs.microsoft.com/ru-ru/aspnet/core/blazor/test
День семьсот сорок седьмой. #ЗаметкиНаПолях #Blazor
10 Функций Blazor, о Которых Вы Вероятно не Знали. Окончание
Начало 1-2
Продолжение 3-4
Продолжение 5-6
Продолжение 7-8

9. Ленивая загрузка кода .NET
В .NET 5.0 для Blazor была добавлена новая инфраструктура для загрузки библиотек по запросу. Загрузка сборок по запросу сокращает время начальной загрузки приложения за счёт откладывания запроса ресурса до тех пор, пока он не понадобится. Хотя поддержка включена в платформу Blazor, она не включена по умолчанию, и Blazor необходимо указать, когда загружать ресурс. Одним из преимуществ ручной настройки является то, что спецификации для загрузки сборки настраиваются в соответствии с потребностями приложения.

Настройка ленивой загрузки
Чтобы включить ленивую загрузку в приложении, необходимо:
1. Описать сборки, которые будут лениво загружаться, в файле конфигурации приложения csproj:
<ItemGroup>
<BlazorWebAssemblyLazyLoad Include="LoadMe.dll" />
</ItemGroup>
2. Зарегистрировать сервис LazyAssemblyLoader посредством внедрения зависимостей в корневой компонент приложения, App.razor:
services.AddScoped<LazyAssemblyLoader>();
3. В App.razor навигация перехватывается с помощью события OnNavigateAsync, которое может использоваться для ленивой загрузки сборок на основе информации о маршруте. При возникновении события сборки извлекаются и загружаются с помощью метода LoadAssembliesAsync сервиса LazyAssemblyLoader:
@inject LazyAssemblyLoader loader
<Router AppAssembly="@typeof(Program).Assembly"
OnNavigateAsync="@OnNavigateAsync">

@code {
private async Task
OnNavigateAsync(NavigationContext args) {
try {
if (args.Path.EndsWith("/lazy")) {
var assemblies =
await loader.LoadAssembliesAsync(
new List<string>(){"LoadMe.dll"});
lazyLoadedAssemblies.AddRange(assemblies);
}
}
catch (Exception ex){…}
}
}

10. Ленивая загрузка JavaScript
В .NET 5.0 появилась возможность отложенной загрузки модулей через JavaScript interop.
@code {
IJSObjectReference module;
string result;
//Загружаем модуль
protected override async
Task OnAfterRenderAsync(bool firstRender) {
if (firstRender) {
module = await JS
.InvokeAsync<IJSObjectReference>(
"import", "./exampleJsInterop.js");
}
}
//вызываем метод модуля
Task Prompt(string message) {
result = await module
.InvokeAsync<string>(
"showPrompt", message);
}
private async ValueTask
IAsyncDisposable.DisposeAsync() {
await module.DisposeAsync();
}
}
При использовании модулей JavaScript важно удалять их, если они больше не нужны. Для этого выше используется метод DisposeAsync.

Источник: https://www.telerik.com/blogs/10-blazor-features-you-probably-didnt-know
День семьсот сорок восьмой. #Оффтоп #КакСтатьСеньором
Что Я Узнал, Чтобы Стать Сеньором
Работник Bloomberg, пришедший туда джуниор-разработчиком, описывает свой опыт роста в компании.

8. Смиритесь со страхом
В прошлом году я работал над второстепенным проектом, который провалился. Это был один из тех проектов, где я изучал новый язык, новый способ ведения дел и проверял гипотезу о нужности такого продукта на рынке. Мне было на удивление сложно продолжать работу над проектом, я чувствовал страх всякий раз, когда думал об этом.

Это был огромный клубок чувств, которые я не мог игнорировать. Но этот опыт помог мне начать замечать и менее выраженные приступы того же чувства, особенно на работе. Когда передо мной стоит грандиозная задача, и я еще не знаю, как её решить, это чувство возвращается. «Ой, как это будет работать? А как реализовать вот это? Я пока не знаю. Я ничего не знаю.»

Я научился принимать и мириться с этим чувством. Теперь это чувство возбуждает меня и стимулирует к действию. Это значит, что я узнаю что-то новое, получу новый навык и стану лучше как специалист. Я зашел так далеко, что начал отслеживать это в моём журнале: «Чувствовал ли я страх на этой неделе?» Если несколько недель подряд я вижу ответ «нет», это значит, что я слишком успокоился и не развиваюсь. Страх - это информация.

Этот мета-навык - замечать, что происходит в мозгу, - является мощным инструментом мониторинга и диагностики. Как Health Check периодически обследует и оценивает «состояние здоровья» программной системы, ведение и периодические обзоры журнала вашего состояния помогают мониторить и улучшают со временем ваше здоровье: умственное и физическое.

Источник: https://medium.com/better-programming/the-things-i-learned-to-become-a-senior-software-engineer-1083686d70cd
Автор оригинала – Neil Kakkar
День семьсот сорок девятый. #юмор
На каком языке вы написали свой первый "Hello World"?
Anonymous Poll
17%
Basic
7%
С
19%
С++
14%
С#
2%
Java
3%
JavaScript
32%
Pascal
1%
PHP
3%
Python
3%
другой
День семьсот пятидесятый. #книги
Сегодня вытащу из чата, чтобы не забыть, интересную книжку. CLR Book, или полное название «Архитектура платформы .NET» от Станислава Сидристого.
«Эта книга задумана как максимально полное описание работы .NET CLR, и частично .NET Framework и призвана в первую очередь заставить посмотреть читателя на его внутреннюю структуру под несколько другим углом: не так, как это делается обычно. Связано это в первую очередь с утверждением, которое может показаться многим очень спорным: любой разработчик обязан пройти школу C/C++. Почему? Да потому что из высокоуровневых эти языки наиболее близки к процессору, и, программируя на них, начинаешь чувствовать работу программы сильнее. Однако мир устроен несколько иначе и у нас зачастую нет никакого времени изучать то, чем мы не будем напрямую пользоваться. Поэтому в книге объяснение всех вопросов идёт с более глубокой, чем обычно, позиции и с более сложными примерами, чтобы у вас возникло чувство понимания работы CLR до последнего винтика.»
Книга доступна бесплатно на GitHub https://github.com/sidristij/dotnetbook

И, чтоб два раза не вставать, ещё одна онлайн книга «Architecture Playbook» от Maikel Mardjan.
«Умные люди думали о том, как создавать ИТ-архитектуры, с самого зарождения компьютеров. Идеи приходят и уходят, однако создание хорошей архитектуры может быть сложным и трудоёмким. Особенно когда пытаешься изобрести велосипед для себя. С помощью этого интерактивного учебника вы сможете лучше и быстрее создать свою ИТ-архитектуру. Основное внимание в этом руководстве уделяется:
1. Повторному использованию знаний.
Зачем снова изобретать велосипед? Гораздо лучше настроить велосипед, под задачи вашей организации или ИТ-проекта. Сосредоточьтесь на сложных проблемах, специфичных для контекста. Используйте известные открытые инструменты и знания для 80% проекта.

2. Более лёгкому созданию архитектурных документов.
В пособии приводится обширный список открытых инструментов, доступных для создания вашей ИТ-архитектуры. Использование этих открытых инструментов ускорит процесс создания и снизит ваши риски.

3. Улучшению качества.
Используя известные шаблоны различных архитектур или их части, вы снизите свои риски. Сложные проекты терпят неудачу. Но если вы воспользуетесь проверенными методами и инструментами, разработанными в результате десятилетий научных исследований ИТ-архитектуры, вы снизите риск для своего проекта.
»

Эта книга также доступна бесплатно, правда, только на английском: https://nocomplexity.com/documents/arplaybook/introduction.html
День семьсот пятьдесят первый.
В чём разница между DTO и POCO? Часть 1: DTO
Некоторые разработчики используют термины DTO и POCO как синонимы. Но правы ли они, и в чём разница между DTO и POCO?

DTO
Data Transfer Object - это объект, предназначенный для передачи данных. По определению DTO должен содержать только данные, без логики или поведения, т.е. не должен содержать методов. В C# DTO должен иметь только свойства, которые должны только получать и устанавливать данные, но не проверять их и не выполнять с ними других операций.

Что насчёт атрибутов и аннотаций данных?
Нет ничего необычного в добавлении метаданных в DTO, чтобы он поддерживал, например, проверку модели. Такие атрибуты не добавляют поведения самому DTO. Поведение находится вне объекта.

А как же модели представления, модели API и т.п.?
Термин DTO ничего не говорит о предполагаемом использовании объекта. Во многих архитектурах DTO могут выполнять несколько ролей. Например, в большинстве архитектур MVC с представлениями, которые поддерживают привязку к типу данных, DTO используются для передачи и привязки данных к представлению (модели представления). В идеале они не должны иметь никакого поведения, только данные, отформатированные так, как этого ожидает представление. Но не все модели представления являются DTO, поскольку в архитектурах MVVM модели обычно включают логику поведения. И даже в приложениях MVC иногда в модель представления добавляется логика, так что они больше не являются DTO.

По возможности называйте свои DTO в соответствии с их предполагаемым использованием. Имя FooDTO не указывает на то, как и где этот тип следует использовать в архитектуре приложения. Вместо этого отдавайте предпочтение именам, раскрывающим намерения, например FooViewModel.
Ниже приведен пример объекта DTO на C#:
public class ProductViewModel {
public int ProductId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal UnitPrice { get; set; }
}

Инкапсуляция и DTO
Инкапсуляция - важный принцип ООП, но он не относится к DTO. Поскольку DTO не имеют операций или поведения и не должны иметь скрытого состояния, они не нуждаются в инкапсуляции. Не усложняйте себе жизнь, используя закрытые мутаторы или пытаясь заставить ваши DTO вести себя как неизменяемые объекты. DTO должны быть простыми в создании, написании и чтении, и поддерживать сериализацию без дополнительных усилий.

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

Неизменяемость и записи
Неизменяемость имеет много преимуществ при разработке ПО, а также может быть полезной функцией в DTO. Неизменяемые DTO были головной болью разработчиков из-за невозможности использовать инициализаторы для свойств только для чтения и ограниченной поддержки сериализаторами. Однако это может измениться с появлением C# 9 и записей. Кстати, вы можете встретить ещё одну аббревиатуру - Data Transfer Record, (DTR). Вот один из способов определить DTR в C# 9 (позиционное объявление):
public record ProductDTO(int Id, string Name, string Description);
Кроме того, можно использовать init-свойства:
public record ProductDTO
{
public int Id { get; init; }
public string Name { get; init; }
}
Init-свойства поддерживают инициализацию при создании, а дальше доступны только для чтения, сохраняя неизменяемость записи. Также записи поддерживают сериализацию даже при позиционном объявлении. Вам может потребоваться несколько подсказок для сериализатора, если вы создадите свой собственный конструктор. Записи набирают популярность с выходом C# 9 и .NET 5, поэтому думаю, что они всё чаще будут использоваться для DTR.

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

Источник:
https://ardalis.com/dto-or-poco/
День семьсот пятьдесят второй.
В чём разница между DTO и POCO? Часть 2: POCO
Часть 1: DTO
Plain Old CLR/C# Object(POCO)
Обычные старые объекты CLR/C#. Что это значит? По сути, это значит, что объект не полагается на определённую структуру или библиотеку для своей работы. POCO может быть создан в любом месте приложения или в тестах, и для его работы не требуется задействовать какую-то конкретную базу данных или фреймворк.

Проще всего продемонстрировать POCO на контрпримере. Следующий класс зависит от некоторых статических методов, которые ссылаются на базу данных, что делает класс полностью зависимым от наличия базы данных для работы. Он также наследуется от типа, определённого в сторонней библиотеке:
public class Product : DataObject<Product> {
public Product(int id) {
Id = id;
Initialize();
}

private void Initialize() {
DataHelpers.LoadFromDB(this);
}

public int Id { get; private set; }
}
Глядя на такое определение класса, представьте, что вы хотите провести модульное тестирование какого-то метода в Product. Вы пишете тест, и первое, что вы делаете, - это создаёте новый экземпляр Product, чтобы вызвать его метод. И ваш тест сразу же терпит неудачу, потому что вы не настроили строку подключения для использования метода DataHelpers.LoadFromDB. Это пример паттерна Active Record, который может значительно усложнить модульное тестирование. Этот класс зависит от способа его хранения. Одной из особенностей POCO является то, что они, как правило, игнорируют способ хранения. Вот пример определения POCO класса:
public class Product {
public Product(int id) {
Id = id;
}
private Product() {
// для EF
}
public int Id { get; private set; }
}

POCO класс не зависит от сторонних фреймворков в отношении поведения или хранения. Он не требует базового класса, особенно базового класса из сторонней библиотеки. У него нет тесной связи со статическими помощниками. Его можно без труда создать где угодно. Он более независим от способа хранения, чем предыдущий пример, хотя и не полностью. Как видно из комментария, этот закрытый конструктор без параметров существует только потому, что он нужен Entity Framework для создания экземпляра при чтении из хранилища.

Также мы можем предположить, что оба этих класса Product включают методы с поведением в дополнение к показанным конструкторам и свойствам. Их можно использовать как объекты DDD в приложении, моделируя состояние и поведение продуктов в системе.

POCO и DTO
Итак, почему же разработчики так часто путают эти два термина? Скорее всего потому, что все DTO являются POCO. Помните, что единственная цель DTO - как можно проще передавать данные. Их должно быть легко создавать, читать и писать. Любая зависимость, которую они могут иметь от специализированных базовых классов, нарушит правила, которые делают класс DTO. Чтобы быть DTO, класс должен быть POCO.

Если было бы верно и обратное, то можно было бы сказать, что эти два термина эквивалентны. Но мы знаем, что это не так. В предыдущем примере Product используется с Entity Framework, имеет закрытый мутатор и поведение, что лишает класс права быть DTO. Но, как мы видели, это хороший пример POCO. Итак, хотя все DTO являются POCO, не все POCO являются DTO.

Источник: https://ardalis.com/dto-or-poco/
День семьсот пятьдесят третий. #оффтоп #юмор
Давненько я не рекомендовал вам видосиков с ютубчика. Поэтому сегодня порекомендую целый канал. Точнее даже два… ну, то есть полтора: оригинал на английском и канал с переводами видео на русский.
Оригинальный канал называется Code Bullet. Автор использует искусственный интеллект для прохождения различных игр вроде тетриса, змейки или Flappy Bird. И делает видео с описанием процесса с уморительными комментариями.

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

Кто предпочитает видео на русском (а они почти все переведены), добро пожаловать на канал Code Wizer И, соответственно, вот вышеупомянутое видео на русском (осторожно, 18+).
День семьсот пятьдесят четвёртый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
77. Начинайте с «Да»
Однажды я бродил по супермаркету, пытаясь найти эдамаме (что, по моему представлению, должно быть каким-то овощем). Я не был уверен, искать его в овощном, в заморозке или в консервах. Я сдался и попросил продавщицу помочь, но она тоже не этого знала!

Она могла ответить мне по-разному. Например, могла пристыдить меня незнанием элементарных вещей, могла просто ткнуть наугад в сторону какого-нибудь отдела или даже просто ответить «нет», лишь бы отвязаться от меня. Но вместо этого она восприняла запрос как возможность найти решение и помочь клиенту. Она позвонила кому-то и через пару минут привела меня к нужному предмету, который находился отделе заморозки.

Сотрудница в этом случае рассмотрела запрос и исходила из того, что надо решить проблему и удовлетворить запрос. Она начала с «да», а не с «нет».

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

В какой-то момент меня осенило, что, возможно, есть другой способ. Может стоит попробовать изменить мой подход и начинать с «да», а не с «нет». И я пришёл к выводу, что это важное качество технического лидера.

Эта простое понимание радикально изменило мой подход к работе. Оказывается, есть много способов сказать «да». Когда кто-то говорит вам: «Слушай, единственное, чего не хватает этому приложению - это сделать все окна круглыми и полупрозрачными!», - вы можете сразу отвергнуть это предложение, а также поставить вопрос о психической вменяемости коллеги. Но часто вместо этого лучше начать с вопроса: «А почему?». Часто существует какая-то реальная и веская причина, по которой этот человек ставит во главу угла круглые полупрозрачные окна. Например, возможно, вы собираетесь заключить контракт с новым крупным клиентом, который требует именно этого.

Чаще всего получается, что, когда вы знаете контекст запроса, открываются новые возможности. Например, иногда даже не надо менять существующий продукт, и можно ответить на запрос «да», не прилагая больших усилий: «На самом деле, в настройках вы можете загрузить скин круглых полупрозрачных окон и использовать его.»

Иногда у другого человека просто может быть идея, идущая в разрез с вашими взглядами на продукт. Мне в таком случае обычно помогает обратить вопрос «Почему?» к себе. Иногда вы можете обнаружить, что веских причин для отказа просто нет, и ваша первоначальная реакция была ошибочной. Возможно, вам придется поднять вопрос на ступеньку выше и привлечь других лиц, принимающих ключевые решения. Помните, цель всего этого - сказать «да» другому человеку и попытаться найти выход, который удовлетворит не только его, но и вас, и всю вашу команду.

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

Начать с «да» означает работать вместе с коллегами, а не против них.

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Alex Miller
День семьсот пятьдесят пятый. #Оффтоп #ЗадачиНаСобеседовании
В сегодняшний праздничный день у меня для вас сразу 2 видео. Наш старый знакомый Nick Chapsas выпустил одно из самых полезных, на мой взгляд, своих видео (в двух частях). Это одна из задач, которые вам могут дать на собеседовании. Она несколько отличается от рассмотренных нами ранее (предыдущие примеры см. по хештегу #ЗадачиНаСобеседовании).

Суть в том, что вам даётся небольшой «легаси» проект, и ваша задача – отрефакторить код, применяя все принципы, которые вы знаете: DRY, KISS, YAGNI, SOLID, вотэтовсё. Также есть ограничения. Например, вам нельзя никак изменять класс Program.cs (возможно и ещё какие-то). Кроме того, вы должны помнить, что класс является частью более крупного проекта, то есть нельзя бездумно менять открытый интерфейс класса. У вас есть обычно два часа. Можно дольше, если обоснуете, зачем вам дополнительное время. В общем, задачка показалась мне очень интересной.

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

Как бы то ни было, просто посмотреть его решение тоже довольно познавательно. Так что выделите час праздничного дня, не пожалеете!
Часть 1: https://youtu.be/U3QvTaw224o
Часть 2: https://youtu.be/Yd4GnWeEkIY
День семьсот пятьдесят шестой. #ЧтоНовенького
Выпущен .NET 6 Preview 1
Кажется, не так давно мы обсуждали вкусности .NET 5, а теперь мы уже переходим к .NET 6. Помню времена, когда даже младшие версии фреймворка иногда содержали огромные изменения. Например, async/await был добавлен в версию .NET Framework 4.5, которая в наши дни означала бы «незначительное» обновление. И вообще, между версиями 1.0 и 4.8 прошло 17 лет.

Первая версия .NET Core была выпущена в 2016 году, и вот мы в 2021 году, всего 5 лет спустя, уже готовы увидеть превью .NET Core 6. Скорость разработки современного программного обеспечения просто поражает. Прошли те времена, когда разработчики запирались в отделах и работали по три года до крупного релиза.

Вы можете скачать .NET 6 Preview 1 здесь: https://dotnet.microsoft.com/download/dotnet/6.0

Что нового?
Как правило, первый предварительный выпуск закладывает основу для будущих новинок и не обязательно содержит большого количества «игрушек», с которыми можно поиграть. Однако некоторые функции действительно были добавлены:
1. Первая итерация переноса Xamarin в .NET для унификации платформ, то есть возможности создавать приложения для Android/IOS в .NET.

2. Первая попытка использования Blazor для настольных приложений (на первый взгляд кажется, что это очень похоже на использование Electron, например, это использование элемента веб-представления в настольных приложениях).

3. Кажется, говорят об улучшении функции горячей перезагрузки. Сложно найти много информации по этому поводу. В .NET CLI уже есть «dotnet watch», но это скорее полная сборка, чем приятная итеративная горячая перезагрузка.

4. Улучшение однофайловых приложений, так чтобы они фактически выполнялись из этого единственного файла, а не распаковывались во временные каталоги. Это уже имело место для однофайловых приложений под Linux в .NET 5, но в .NET 6 эта функциональность была расширена для Windows и Mac.

5. appsettings.json в Visual Studio и VSCode (с расширением C#) теперь имеет автозаполнение для часто используемых конфигураций в ASP.NET Core, включая настройку ведения журнала, фильтрации хостов и Kestrel.

6. WPF теперь поддерживается в ARM64.

Основной путь изменений в .NET 6 (и даже .NET 5) - это объединение различных платформ и фреймворков, которые находятся под знаменем .NET. В .NET 5 это была в основном разработка для настольных компьютеров, а в .NET 6 - это разработка мобильных приложений с Xamarin.

Источник: https://dotnetcoretutorials.com/2021/02/21/net-6-preview-1-has-been-released/
День семьсот пятьдесят седьмой. #Оффтоп #ЗадачиНаСобеседовании
Что я Узнал о C# из Собеседований. Начало
Недавно я прошел серию собеседований в нескольких крупнейших технологических компаниях. Процессы собеседований в них сильно отличались, но у них также было много общего, например, упор на задачи на написание кода. Сортировка, нахождение всех возможных комбинаций или нахождение выхода из лабиринта. Я не знаю, как это связано с реальной разработкой ПО. Я не помню, чтобы мне когда-либо приходилось самому писать алгоритм сортировки в повседневной работе. Тем не менее, очевидно, что разработчик, способный решить эти проблемы, будет лучше справляться и с проблемами реальной жизни. Поэтому я хочу описать, что я узнал о C# во время собеседований. У меня больше 10 лет опыта в C#, но повседневная разработка и прохождение интервью – это разные вещи.

1. Многомерные массивы могут быть полезны
Не думаю, что я когда-либо использовал многомерный массив в своей работе. Конечно, я иногда использовал список списков List<List<T>> и, возможно, список массивов List<int[]>, а иногда даже список словарей массивов List<Dictionary<int,string[]>>. Но я обнаружил, что многомерные массивы очень полезны в упражнениях по кодированию.

Многомерные массивы - это не то же самое, что массивы массивов, например int[][] (зубчатые массивы). Последние представляют собой набор массивов, каждый из которых может иметь разную длину. Многомерный массив больше подходит для решения общих задач, таких как представление двухмерного лабиринта или трехмерного куба. Если вы собираетесь на собеседование в ближайшее время, освежите в голове синтаксис:
int[,] arr = new int[3, 2]
{{1, 2},{3, 4},{5, 6}};

int dimLen1 = arr.GetLength(0); //3
int dimLen2 = arr.GetLength(1); //2
var p00 = arr[0, 0]; //1
var p01 = arr[0, 1]; //2
var p10 = arr[1, 0]; //3

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

2. Используйте кортежи, вместо классов
Я довольно редко использую кортежи. Вероятно потому, что я пока не привык к их более красивому синтаксису. Обычно я выбираю класс или структуру. Классы делают код более структурированным и, возможно, более читаемым. Но на самом деле у кортежей очень хороший и, что важно, более компактный синтаксис. Писать нужно меньше, менять нужно меньше. Эти вещи действительно важны на собеседовании. Нужно тратить минимум времени на ввод кода, чтобы у вас было больше времени на размышления.

Допустим, у меня есть метод, который возвращает точку в трёхмерном массиве. При использовании класса я бы написал:
class Point3D {
public int X { get; set; }
public int Y { get; set; }
public int Z { get; set; }
}
private Point3D Calc() {…}

Тогда как с кортежами всё проще:
private (int X, int Y, int Z) Calc(){ ... }

Имейте в виду, что на собеседовании вы будете писать в своего рода онлайн-блокноте, где у вас нет сниппетов, автозаполнения и прочих прелестей, к которым вы привыкли в Visual Studio.

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

Источник:
https://michaelscodingspot.com/what-i-learned-about-c-from-job-interviews/
Автор: Michael Shpilt.
День семьсот пятьдесят восьмой. #Оффтоп #ЗадачиНаСобеседовании
Что я Узнал о C# из Собеседований. Продолжение
Начало

3. Бинарные операции – это вещь!
Как часто вы используете операторы <<, >>, & и | в ваших приложениях? Думаю, не часто. Я тоже, но они могут быть довольно полезны. Небольшое напоминание:
int a = 15;
Convert.ToString(a, to_base: 2); //1111
//сдвиг вправо дважды (деление на 4)
a = a >> 2; //11
//сдвиг влево трижды (умножение на 8)
a = a << 3; //11000
a = a & 0b_11111; // не изменяется
// остаётся 1000, т.к. левый бит обнуляется
a = a & 0b_1111; //1000
a = a | 0b_1; // становится 1001
a = a | 0b_110; // становится 1111

Одна из особенностей двоичного исчисления заключается в том, что итерация по основанию 2 может быть полезна в задачах на перестановку. Например: для заданного массива элементов, распечатать все возможные комбинации этих элементов, в которых каждый элемент может либо присутствовать, либо отсутствовать. Порядок не имеет значения. То есть для массива ["a", "b", "c"] вывод будет следующим:
"", a, b, c, ab, ac, bc, abc

Теперь рассмотрим итерацию в двоичном формате от 0 до 2^3. Если каждая цифра описывает элемент массива, который присутствует или нет, то это один из способов распечатать все возможные итерации. Требуемый выше результат можно описать как:
000, 001, 010, 100, 110, 101, 011, 111

4. Полезные штуки со строками и массивами
Большинство методов, используемых в задачах, аналогичны методам, используемым в реальной жизни. Для строк это .Substring, .Contains, .Replace, string.Equals, .ToLower, .ToUpper и т.д. Один из методов, полезных в этих задачах, но редко используемый в моей работе, - это string.Join:
var joined = string.Join(",", 
new[]{"a","b","c"}); // "a,b,c"

Для массивов есть полезный метод Array.Sort, который может принимать делегат Comparison<T> для нужной вам сортировки. Предположим, вы хотите отсортировать группу строк по последней букве:
var words = new[]{"cat", "job", "zebra", "row"};
Array.Sort(words, (w1, w2) => {
var last1 = w1[w1.Length-1];
var last2 = w2[w2.Length-1];
return last1 < last2 ? -1 : 1;
//как вариант last1.CompareTo(last2);
});
// zebra, job, cat, row

Еще один полезный метод - Array.Copy. Помимо прочего, он может копировать фрагмент массива в новый массив:
var words = new[]{"cat", "job", "zebra", "row"};
string[] dest = new string[2];
Array.Copy(words, sourceIndex: 1,
dest, destinationIndex: 0, length: 2);
// job, zebra

Конечно, есть и другие способы это сделать, например, LINQ или с помощью диапазонов.

Источник: https://michaelscodingspot.com/what-i-learned-about-c-from-job-interviews/
Автор: Michael Shpilt.
День семьсот пятьдесят девятый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
78. Шаг назад и автоматизация, автоматизация, автоматизация
Я работал с программистами, которые, когда их просили произвести подсчёт строк кода в модуле, вставляли все файлы в один текстовый редактор и использовали его функцию подсчёта строк. Затем они делали это снова на следующей неделе. И через неделю. Это было плохо.

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

Итак, почему люди выполняют одну и ту же задачу снова и снова, вместо того чтобы остановиться, сделать шаг назад и потратить время на её автоматизацию?

Распространённое заблуждение №1: автоматизация предназначена только для тестирования
Конечно, автоматизация тестирования - это здорово, но зачем останавливаться на достигнутом? В любом проекте изобилуют повторяющиеся задачи: контроль версий, компиляция, упаковывание, создание документации, развёртывание и отчетность. Для многих из этих задач скрипт окажется мощнее, чем мышь. Выполнение утомительных задач станет быстрее и надёжнее.

Распространённое заблуждение №2: у меня есть IDE, поэтому мне не нужно автоматизировать
Вы когда-нибудь использовали аргумент «Но это работает на моей машине?» в спорах с товарищами по команде? Современные IDE имеют тысячи потенциальных настроек, и практически невозможно гарантировать, что все члены команды имеют одинаковые конфигурации. Системы автоматизации сборки дадут вам контроль и повторяемость результата.

Распространённое заблуждение №3: чтобы автоматизировать это, мне нужно изучить экзотические инструменты
Вы можете пойти по длинному пути, используя полноценный консольный язык, например, bash или Power-Shell, и систему автоматизации сборки. Если же вам нужно взаимодействовать с веб-сайтами, можно использовать такие инструменты, как Selenium.

Распространённое заблуждение №4: я не могу автоматизировать эту задачу, потому что не могу работать с этим форматом файлов
Если для части вашего процесса требуются документы Word, электронные таблицы или изображения, это действительно может быть сложно автоматизировать. Но действительно ли это необходимо? Можете ли вы использовать обычный текст? CSV файлы вместо таблиц? XML/JSON? Часто небольшая подгонка процесса под автоматизацию может дать хорошие результаты и значительно снизить трудозатраты.

Распространённое заблуждение №5: у меня нет времени разбираться в этом
Вовсе не обязательно зазубрить все команды bash. Учитесь на ходу. Когда у вас есть задача, которую, по вашему мнению, можно и нужно автоматизировать, узнавайте об инструментах автоматизации ровно столько, сколько вам нужно. И делайте это на ранних этапах проекта, когда обычно легче найти время. Как только вы добьетесь успеха, вы (и ваш начальник) увидите, что имеет смысл инвестировать в автоматизацию.

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Cay Horstmann
👍1