TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #3128 2.06K
День 2605. #ЗаметкиНаПолях
5 Малоизвестных Функций C#, Которые Упростят Вашу Жизнь

Фреймворк уже имеет надёжные инструменты для решения различных проблем, но многие из них мало известны. Сегодня рассмотрим некоторые.

1. OperatingSystem.IsX вместо RuntimeInformation
В течение многих лет проверка текущей ОС в .NET означала написание чего-то вроде:
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
//…
}

Теперь появились более чистые варианты:
- OperatingSystem.IsWindows,
- OperatingSystem.IsLinux,
- OperatingSystem.IsMacOS
и т.п.
if (OperatingSystem.IsWindows())
{
//…
}


2. Правильная изоляция плагинов с помощью AssemblyLoadContext
Если вы когда-либо пытались создать систему плагинов в .NET, вы знаете, насколько болезненны конфликты сборок. Загрузите две версии одной и той же зависимости, и внезапно всё перестаёт работать. AssemblyLoadContext позволяет загружать сборки изолированно, так что два плагина могут зависеть от разных версий одной и той же DLL, не мешая друг другу. Вот минимальный код для начала:
class PluginLoadContext : AssemblyLoadContext
{
private AssemblyDependencyResolver _resolver;

public PluginLoadContext(string path) =>
_resolver = new(path);

protected override Assembly? Load(AssemblyName name)
{
var path = _resolver
.ResolveAssemblyToPath(name);

return path != null
? LoadFromAssemblyPath(path)
: null;
}
}

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

3. Разбор зависимостей с помощью AssemblyDependencyResolver
AssemblyDependencyResolver, получив путь к плагину или сборке, определяет, откуда должны браться зависимости:
var resolver = 
new AssemblyDependencyResolver(pluginPath);
var path = resolver
.ResolveAssemblyToPath(assemblyName);

Вы получаете правильные правила разрешения зависимостей, соответствующие тому, как это обычно делает .NET, но с областью действия в контексте плагина. Так вы избегаете неприятных сюрпризов, когда плагин ссылается на Newtonsoft.Json 13.0.1, а хост-приложение использует 12.0.3.

4. Получение версий сборок без ошибок
Часто в коде можно встретить что-то такое:
var version = Assembly
.GetExecutingAssembly()
.GetName()
.Version;

Дело в том, что это значение не всегда совпадает с версией, которую вы указали в проекте. Это версия сборки, а не обязательно версия файла или информационная версия. Какая из них вам нужна?
- AssemblyName.Version - версия сборки, полученная во время компиляции,
- FileVersionInfo.GetVersionInfo(assembly.Location).FileVersion - версия файла,
- AssemblyInformationalVersionAttribute - семантическая версия, вроде 1.0.0-beta+sha.abc123.

Лучший подход – выражаться более явно:
var version = Assembly
.GetExecutingAssembly()
.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?
.InformationalVersion;

Так вы получите именно ту строку, которую хотели передать, а не то, что MSBuild по умолчанию присвоил вашей DLL.

5. Получение зависимостей из контейнера с помощью ActivatorUtilities
Иногда нужно создать объект, который не зарегистрирован в контейнере, но имеет зависимости, которые зарегистрированы. Используйте ActivatorUtilities:
var myService = ActivatorUtilities
.CreateInstance<MyService>(serviceProvider);

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

Источник: https://blog.stackademic.com/if-youre-not-using-these-5-net-features-you-re-working-too-hard-0aefbf5a6fdc?gi=bb3ac273e638
  • 👍 15
More from @netdeveloperdiary
  1. Sep 27, 2026День 2797. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Окончание Начало Продол…
  2. Sep 26, 2026День 2796. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Продолжение Начало Три…
  3. Sep 25, 2026День 2795. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Начало Проблема с позиц…
  4. Sep 24, 2026День 2794. #Оффтоп #Здоровье Сегодня будет необычный пост. Завтра в Москве стартует конфер…
  5. Sep 23, 2026День 2793. #ЗаметкиНаПолях #SQL 10 Редких Возможностей SQL, Которые Стоит Знать Каждому. Ч…
  6. Sep 22, 2026День 2792. #ЗаметкиНаПолях #SQL 10 Редких Возможностей SQL, Которые Стоит Знать Каждому. Ч…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →