C# (C Sharp) programming
18.7K subscribers
880 photos
47 videos
8 files
736 links
По всем вопросам- @haarrp

C# - обучающий канал Senior C# разработчика.

@ai_machinelearning_big_data - Machine learning

@itchannels_telegram - 🔥лучшие ит-каналы

@csharp_ci - C# академия

@pythonlbooks- книги📚

Реестр РКН: https://clck.ru/3Fk3kb
Download Telegram
Что выведет на экран этот код?
Anonymous Quiz
14%
1,2,3 1,2,3
6%
1,2,3 0,0,0
42%
42,2,3 0,0,0
32%
42,2,3 42,2,3
7%
🥒
🔥На Stepik вышел курс: Linux: полный апгрейд твоих скиллов

Хочешь реально понимать, что происходит под капотом твоей системы, а не просто кликать по GUI?

Без глубокого знания базы ты не инженер - ты просто пользователь.

🔹 В курсе ты:

- Освоишь bash, grep, sed, awk - инструменты, которыми живут админы.
- Разберёшь права, процессы, сеть, файловую систему и научишься чинить всё, что падает.
- Настроишь SSH, firewall, systemd, crontab, демоны и автозапуск.
- Научишься анализировать логи, следить за нагрузкой, и не паниковать при 100% CPU.

💡 Формат: пошаговое объяснение базы и разбор важных практик по работе с Linux.

🎯 После курса ты: будешь чувствовать Linux как родную среду и забудешь, что такое “permission denied”.

🚀 24 часа действует скидка 30%

👉 Учиться со скидкой
⚡️ Guard Clauses в .NET: проверяй ошибки одной строкой

Хочешь упростить код и избавиться от вложенных if? Используй guard clauses — быстрые проверки входных данных в самом начале метода.

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

В новых версиях .NET появилось много встроенных проверок:

.NET 6:
- ArgumentNullException.ThrowIfNull

.NET 7:
- ArgumentException.ThrowIfNullOrEmpty

.NET 8:
- ThrowIfNullOrWhiteSpace
- ThrowIfNullOrEmpty (для коллекций)
- ThrowIfZero
- ThrowIfNegative
- ThrowIfGreaterThan

Когда это особенно полезно:
- в сервисах и API для валидации входных данных
- в доменных моделях — чтобы не допустить невалидного состояния
- в конструкторах и фабриках

Главная мысль:
Guard clauses — это не про «больше проверок»,
а про ранний отказ и чистую архитектуру.


public class Order
{
public Order(string customerName, decimal amount)
{
ArgumentException.ThrowIfNullOrWhiteSpace(customerName);
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(amount);

CustomerName = customerName;
Amount = amount;
}

public string CustomerName { get; }
public decimal Amount { get; }
}
✔️ Unity обещает создание игр через текстовые команды.

CEO Unity Мэтт Бромберг определил "AI-driven authoring" как приоритетное направление развития компании на 2026 год. Компания готовит инструмент, который сможет собирать казуальные игры с нуля, используя только естественный язык.

Бета-версию Unity AI покажут на GDC в марте 2026 года. Технология будет работать нативно внутри платформы, Unity возьмет топовые внешние модели и доучит их понимать контекст движка.

В компании уверены, что такой подход даст результат лучше, чем попытки заставить универсальные LLM писать сложный игровой код. Цель - окончательная демократизация геймдева, порог входа в который, похоже, скоро исчезнет совсем.
wccftech.com
Please open Telegram to view this post
VIEW IN TELEGRAM
Что выведет на экран этот код?
Anonymous Quiz
19%
enum, enum, enum
14%
enum, enum, object
52%
enum, object, object
7%
object, object, object
8%
🥒
⚡️ КАСТОМИЗАЦИЯ ИСТОРИИ МИГРАЦИЙ В ENTITY FRAMEWORK

В Entity Framework можно гибко настроить таблицу истории миграций и это полезно в реальных проектах.

По умолчанию EF создаёт таблицу __EFMigrationsHistory в стандартной схеме (dbo).
Но часто требуется:

- вынести её в отдельную схему
- изменить имя таблицы
- разделить миграции между модулями
- привести структуру БД к корпоративным стандартам

Это можно сделать прямо при настройке DbContext через метод MigrationsHistoryTable.



services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(
connectionString,
sqlOptions =>
{
sqlOptions.MigrationsHistoryTable(
tableName: "MigrationHistory",
schema: "infrastructure"
);
}));


// Теперь EF будет хранить историю миграций в:
// infrastructure.MigrationHistory
Please open Telegram to view this post
VIEW IN TELEGRAM
⚡️ Async-коммуникация ломает интеграционные тесты.

Вы отправляете событие в одном модуле… и что дальше? Ждать?

Если используете Thread.Sleep — готовьтесь к:
- медленным тестам
- flaky-поведению
- падениям в CI/CD

Решение — не ждать. Опрос (Polling).

Я использую паттерн Retry Assertion для тестирования асинхронного взаимодействия между модулями:

Как это работает:

1. Выполняем команду (Модуль A)
2. Периодически выполняем запрос (Модуль B)
3. Ждём, пока результат появится
4. Делаем assert

Пример:


var userId = await Sender.Send(new RegisterUserCommand(...));

var result = await Poller.WaitAsync(
TimeSpan.FromSeconds(15),
async () =>
{
return await Sender.Send(new GetCustomerQuery(userId));
});

result.Should().NotBeNull();
result.IsSuccess.Should().BeTrue();
Динамическая строка подключения в EF Core - когда и зачем это нужно

Факт
В EF Core можно задать connection string динамически при регистрации DbContext. Для этого используется делегат, который выполняется в момент получения контекста из DI.

Как это работает

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

Пример


builder.Services.AddDbContext<OrdersDbContext>((sp, o) =>
{
var tenantProvider = sp.GetRequiredService<TenantProvider>();
var connectionString = tenantProvider.GetConnectionString();

o.UseSqlServer(connectionString);
});


Dynamic DbContext configuration - ключевой паттерн для масштабируемых multi-tenant систем.
Если приложение растёт и базы начинают разделяться по клиентам или регионам, этот подход становится стандартом архитектуры.
🖥 Асинхронщина ломает интеграционные тесты? Есть простой паттерн

Проблема:

Вы отправляете событие в одном модуле…
И начинаете ждать.

Если используете Thread.Sleep
готовьтесь к:
- медленным тестам
- flaky-падениям
- ненависти от CI/CD

Решение — Retry Assertion (Polling)

Как работает паттерн:

1. Выполняем команду (Module A)
2. Периодически опрашиваем состояние (Module B)
3. Ждём, пока результат появится
4. Делаем assert

Схема:

- Execute Command (Module A)
- Poll Query (Module B) until result != null
- Assert

Почему это лучше:

- Нет случайных падений
- Тесты работают быстрее
- Полностью детерминированное поведение
- Отлично подходит для async, событий и modular monolith

Главная идея:

Не жди фиксированное время — жди состояние.

Такой подход превращает нестабильные интеграционные тесты в надёжные и быстрые.
Please open Telegram to view this post
VIEW IN TELEGRAM
💡 Soft delete в EF Core без лишней логики в сервисах

Удалять данные физически — не всегда хорошая идея.
Логи, аудит, восстановление, аналитика — всё это требует soft delete.

Вот удобный способ реализовать его через EF Core interceptor.

Что делает перехватчик:

- Проверяет ChangeTracker на сущности с интерфейсом ISoftDeletable
- Если состояние сущности — Deleted
- Меняет его на Modified
- Устанавливает:
- IsDeleted = true
- DeletedOnUtc = DateTime.UtcNow

В итоге:

Вы вызываете обычный:

context.Remove(entity);


А в базе:

- запись не удаляется
- просто помечается как удалённая

Плюсы подхода:

- никакой логики soft delete в сервисах и репозиториях
- единая точка обработки
- чистый доменный код
- безопасное удаление по всему приложению

Важно:

Если у вас есть связанные сущности (navigation properties),
перехватчик нужно дополнительно расширить — каскадное soft-удаление EF Core не делает автоматически.

Soft delete через interceptor — это один из самых чистых production-подходов для EF Core.

#dotnet #EFCore #Backend #Architecture #CSharp