C# 1001 notes
Ir al canal en Telegram
Регулярные короткие заметки по C# и .NET. Просто о сложном для каждого. admin - @haarrp
Mostrar más6 685
Suscriptores
-424 horas
-47 días
+3130 días
Archivo de publicaciones
6 684
🖥 Моя коллекция 50+ вопросов для собеса C#
https://habr.com/ru/articles/801369/
@csharp_1001_notes
6 684
🖥 Интересная статья о паттерне «Спецификация» в С#
⏩О чём статья?
О паттерне «Спецификация», который позволяет улучшить структуру приложения, и, следовательно, увеличить гибкость, уменьшив при этом объем кода, а значит - сократить количество ошибок, но это не точно.
⏩К статье приложен пример Web API приложения, написанный с использованием анемичной доменной модели, библиотеки MediatR, Postgres и Docker Compose. Всё, как Вы любите и, таки да, анемичной доменной моделью мы нарушим инкапсуляцию, без этого никуда.
📎 Статья
@csharp_1001_notes
6 684
Из бариста в бэкенд-разработчики, из офис-менеджера в UX-дизайнеры. Такие истории интригуют и вдохновляют. Но будут ли работодатели в IT серьёзно воспринимать вас, если вы закончите онлайн-курс?
Расскажем, что мы делаем в Яндекс Практикуме, чтобы так и было.
→ Бесплатно, 21 марта в 18:00 Мск
На большом онлайн-событии покажем учёбу в Практикуме изнутри. Вы узнаете:
— кто поддерживает студентов и не даёт опустить руки до самого трудоустройства;
— почему мы добавили в свою платформу YandexGPT и как нейросеть помогает учиться;
— кто передаёт студентам знания и навыки, которые нужны в IT прямо сейчас;
— как студенты становятся готовыми практиками.
→ Зарегистрироваться на онлайн-событие
6 684
🖥 В чем преимущества асинхронного кода на C#?
Разберём на примере.
⏩Вот, полностью асинхронный код:
Console.WriteLine("Start Main");
// Запускаем задачу PrintAsync и спокойно идём дальше
var printTask = PrintAsync();
Console.WriteLine("End Main");
// Ждём завершения задачи PrintAsync
await printTask;
async Task PrintDelayAsync()
{
// Ждём 3 секунды, но при этом поток не будет занят
await Task.Delay(3000);
Console.WriteLine("Print");
}
async Task PrintAsync()
{
Console.WriteLine("Start PrintAsync");
// Ждём пока метод отработает, но поток не занят
await PrintDelayAsync();
Console.WriteLine("End PrintAsync");
}
⏩Весь этот код может выполняться даже одним потоком, при этом в моменты ожидания await этот поток освобождается может выполнять какие-то другие асинхронные задачи из вашего кода, если они у вас будут.
⏩Пример параллельного исполнения задач:
Console.WriteLine("Start Main");
await PrintAsync();
Console.WriteLine("End Main");
async Task Print1Async()
{
await Task.Delay(3000);
Console.WriteLine("Print 1");
}
async Task Print2Async()
{
await Task.Delay(2000);
Console.WriteLine("Print 2");
}
async Task Print3Async()
{
await Task.Delay(1000);
Console.WriteLine("Print 3");
}
async Task PrintAsync()
{
Console.WriteLine("Start PrintAsync");
var tasks = new List<Task>() { Print1Async(), Print2Async(), Print3Async() };
await Task.WhenAll(tasks);
Console.WriteLine("End PrintAsync");
}
⏩Вывод:
Start Main Start PrintAsync Print 3 Print 2 Print 1 End PrintAsync End Main⏩То есть суть в чём — запустились сразу 3 задачи, выполнились они не в том порядке, как были запущены, а где меньше задержка, та раньше и выполнилась. При этом, повторюсь, достаточно одного потока, чтобы выполнять этот код. Что очень существенно, когда речь идёт о сильно загруженных программах типа веб-сервера или какого-то обработчика данных реального времени. @csharp_ci
6 684
Вариант для тех, кто ищет виртуальный сервер с хорошей веб-защитой — Aéza:
– Виртуальные сервера до 6.0 ГГц на лучших процессорах;
– Профессиональная фильтрация атак StormWall;
– Круглосуточная поддержка;
– Anycast фильтрация;
– Низкие цены;
– 15% кешбэка по ссылке.
Бесконечно можно смотреть на три вещи: на огонь, воду и скидку от Aeza!
Говорят: твоё от тебя не уйдет. А зачем ждать? Динозавры тоже ждали и остались в прошлом
Используй 50% скидку и погнали в будущее!
Кроме того, сейчас Aéza раздает личные бесплатные сервера, забираем тут. Регистрация, подписка, платежи не потребуются.
Реклама. Индивидуальный предприниматель Лобанов Леонид Константинович. ИНН 781625705648 erid: LjN8KEr3S
6 684
🖥 Обработка ошибок с помощью IExceptionHandler в ASP.NET Core 8.0
Относительно недавно на свет появился ASP.NET Core 8.0, и теперь можно обрабатывать ошибки с помощью
IExceptionHandler.
А вот и полезная статья о том, как это делать.
⏩Вкратце о IExceptionHandler
IExceptionHandler — это интерфейс, который предоставляет разработчику обратный вызов для обработки известных исключений в центральном расположении.
IExceptionHandler реализации регистрируются путем вызова IServiceCollection.AddExceptionHandler. Время существования экземпляра IExceptionHandler — одноэлементное. Можно добавить несколько реализаций, и они вызываются в порядке регистрации.
Если обработчик исключений обрабатывает запрос, он может вернуться true к остановке обработки. Если исключение не обрабатывается обработчиком исключений, то элемент управления возвращается к поведению по умолчанию и параметрам из по промежуточного слоя. Для обработки и необработанных исключений создаются различные метрики и журналы.
📎 Статья
📎 Доки от Windows, как обрабатывать ошибки
@csharp_ci6 684
🖥 Задание C#
Задача: реализуй на C# метод расширения для строки, который будет проверять, является ли данная строка палиндромом.
Палиндром — это слово/фраза/последовательность символов, которая читается одинаково в обе стороны ("шалаш", "ротор", "12321")
Получилось?
Можешь смотреть код возможного решения
@csharp_ci
6 684
🖥 Новый пример, показывающий, как использовать открытые API-интерфейсы телеметрии с
aspire dashboard, работающим как автономный контейнер.
https://learn.microsoft.com/en-us/samples/dotnet/aspire-samples/aspire-standalone-dashboard/
@csharp_ci6 684
🚀 Text2sql
Нейросеть, специализирующаяся на написании SQL-запросов (и не только) по текстовому описанию
Описание:
A Regex expression to match a password that contains at least one lowercase letter, one uppercase letter, one digit, one special character, and is at least 8 characters longОтвет нейросети:
^(?=.*d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*()_+}{":;'/?.><,])(?=.*[^s]).{8,}$
🔗 text2sql.ai
@sqlhub6 684
⚡Онлайн-Хакатон "Городские Легенды" от Группы компаний Росохрана и ООО «Эпсилон»!
💡Кейсы хакатона:
1. Разработка интерактивного голосового помощника с использованием анимированного аватара.
2. Интеграция интерактивного аватара в городскую экосистему цифровых сервисов.
👨💻Для кого хакатон?
- C++/C#-разработчиков;
- Unity-разработчиков;
- 3D-Моделлеров;
- UX/UI-дизайнеров;
- AI-Специалистов;
- Команды из 5 человек;
- Готовых внедрить любимых персонажей в городскую среду и побороться за главный приз!
🏆Общий призовой фонд - 700 000 рублей!
📅Дата проведения: 11-18 Марта
📍Формат: Онлайн
Подробная информация и регистрация: https://tglink.io/05539cf28394?erid=LjN8KWcqb
6 684
⚡️ Каждый разработчик должен знать о тестовых контейнерах. Это отличный инструмент, который нужно знать и применять, когда он вам понадобится.
Вот пример работы с Testcontainersна .NET:
https://testcontainers.com/guides/getting-started-with-testcontainers-for-dotnet/
#dotnet #csharp #fsharp
@csharp_1001_notes
6 684
🖥 Параллельная Публикация Уведомлений в MediatR
MediatR — это популярная библиотека с простой реализацией паттерна посредник в .NET.
Посредник — паттерн шаблон проектирования, обеспечивающий взаимодействие множества объектов, формируя при этом слабое зацепление и избавляя объекты от необходимости явно ссылаться друг на друга.
С ростом популярности паттерна CQRS MediatR стала популярной библиотекой для реализации команд и запросов.
Издатель — подписчик — поведенческий шаблон проектирования передачи сообщений, в котором отправители сообщений, именуемые издателями (англ. publishers), напрямую не привязаны программным кодом отправки сообщений к подписчикам (англ. subscribers).
Но она также поддерживает паттерн издатель-подписчик с использованием уведомлений. Можно опубликовать экземпляр INotification, и несколько подписчиков обработают опубликованное сообщение.
Разберемся как это можно делать параллельно.
Нам нужен класс, реализующий INotification:
public record OrderCreated(Guid OrderId) : INotification;
А также реализация соответствующего INotificationHandler:
public class OrderCreatedHandler :
INotificationHandler<OrderCreated>
{
private readonly INotificationService svc;
public OrderCreatedHandler(
INotificationService service)
{
svc = service;
}
public async Task Handle(
OrderCreated notification,
CancellationToken ct)
{
await svc.SendOrderCreatedEmail(
notification.OrderId,
ct);
}
}
Теперь можно публиковать сообщение с помощью IMediator или IPublisher:
await publisher.Publish(
new OrderCreated(order.Id),
cancellationToken);
MediatR вызовет все соответствующие обработчики. До 12й версии MediatR стратегия публикации вызывала каждый обработчик по отдельности. Однако появился новый интерфейс INotificationPublisher, управляющий тем, как вызываются обработчики.Реализация по умолчанию - ForeachAwaitPublisher:
public class ForeachAwaitPublisher
: INotificationPublisher
{
public async Task Publish(
IEnumerable<NotificationHandlerExecutor> executors,
INotification notification,
CancellationToken ct)
{
foreach (var e in executors)
{
await e
.HandlerCallback(notification, ct)
.ConfigureAwait(false);
}
}
}
Она вызывает обработчики по одному и завершается неудачей при ошибке в одном из обработчиков.Но вы также можете использовать TaskWhenAllPublisher (показаны только отличия в реализации метода Publish:
var tasks = executors
.Select(e =>
e.HandlerCallback(notification, ct))
.ToArray();
return Task.WhenAll(tasks);
TaskWhenAllPublisher вызывает все обработчики одновременно и выполняет их все независимо от того, возникали ли в них ошибки. Если вы сохраните задачу, возвращенную TaskWhenAllPublisher, вы можете получить доступ к свойству Task.Exception, содержащему экземпляр AggregateException, и реализовать обработку исключений.Настройка стратегии публикации происходит в методе AddMediatR. Если вы хотите использовать стратегию TaskWhenAllPublisher, вы можете: - указать значение для свойства NotificationPublisher (тогда издатель будет синглтоном), - указать тип стратегии в свойстве NotificationPublisherType и использовать свойство ServiceLifetime для задания времени жизни:
services.AddMediatR(cfg => {
…
cfg.NotificationPublisher =
new TaskWhenAllPublisher();
// или
cfg.NotificationPublisherType =
typeof(TaskWhenAllPublisher);
cfg.ServiceLifetime = ServiceLifetime.Transient;
});
Вы также можете реализовать пользовательский экземпляр INotificationPublisher и вместо этого использовать собственную реализацию.Плюсы Параллельного запуска обработчиков уведомлений обеспечивает значительное повышение производительности по сравнению с поведением по умолчанию. Однако обратите внимание, что все обработчики будут использовать одну и ту же область видимости. Если у вас есть экземпляры сервисов, которые не поддерживают конкурентный доступ, вы можете столкнуться с проблемами. К сожалению, одним из таких является EF Core DbContext. 📌 Подробнее @csharp_1001_notes
6 684
⚡️ AspNetCore.ApiGateway
Представляем крутой инструмент: микросервис с конвейером запросов #ASPNETCore.
Без проблем перейдите от веб-интерфейса #ASPNETCore к Veritas API Gateway, в который входят, Swagger, методы авторизации, фильтры, балансировщик нагрузки и многое другое.
▪ Github
@csharp_1001_notes
6 684
System.IO.Hashing - это действительно полезный пакет
NuGet для некриптографического хэширования в .NET.
📌Узнать о нем подробнее6 684
6 684
Стоит ли становиться Rust-разработчиком в 2024 и как это сделать?
💻Узнайте на бесплатном практическом уроке от OTUS, где вы вместе с опытным экспертом:
- обсудите основные направления развития языка и его инфраструктуры;
- рассмотрите наиболее востребованные навыки по этим направлениям;
- разберёте типичное собеседование на должность Rust-разработчика в различных областях.
Встречаемся 26 февраля в 20:00 мск в рамках курса «Rust Developer. Professional». Доступна рассрочка на обучение!
👉Пройдите короткий тест прямо сейчас, чтобы посетить бесплатный урок и получить запись: https://tglink.io/4c0293ce6c0c?erid=LjN8KWx1q
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
6 684
EF 8 генерирует бодее эффективные запросы, используя
IN вместо EXISTS, когда метод Contains используется с подзапросом.
Разницу в запросах вы можете увидеть в примере на картинке.
@csharp_1001_notes6 684
🖥 Паттерн Хранитель (Memento) - поведенческий шаблон проектирования, позволяющий, не нарушая инкапсуляцию, зафиксировать и сохранить внутреннее состояние объекта так, чтобы позднее восстановить его в это состояние.
Шаблон Хранитель используется, когда:
▪необходимо сохранить снимок состояния объекта (или его части) для последующего восстановления
▪прямой интерфейс получения состояния объекта раскрывает детали реализации и нарушает инкапсуляцию объекта
В C# паттерн Memento может быть реализован с помощью комбинации трех классов:
Originator, Memento и Caretaker.
▪ Подробнее
@csharp_1001_notes6 684
Учитесь тому, что пригодится в работе и в жизни — бесплатно, с Яндекс Практикумом.
Тут на одной странице собраны курсы, которые помогут попробовать себя в разных IT-профессиях и получить практический навык. 17 разных курсов по программированию, аналитике данных, маркетингу, менеджменту и дизайну. Прохождение занимает от 2 до 20 часов.
Например, можно разобраться в основах Java, научиться искать и нанимать тестировщиков, задизайнить плакат для фестиваля еды и ещё много чего.
Выбирайте курс по душе и пробуйте себя в разных профессиях!
6 684
🖥 Устойчивость приложений и хаос-инженерия
Эта статья знакомит с концепцией отказоустойчивости и хаос-инженерии в приложениях .NET с использованием библиотеки Polly и рассказывает о новых возможностях, позволяющих использовать хаос-инженерию.
В ней приведено практическое руководство по интеграции стратегий хаоса в HTTP-клиенты и показывается, как настраивать конвейеры отказоустойчивости для повышения эффективности работы вашего приложения.
▪Статья
▪Polly
@csharp_1001_notes
