.
.NET Разработчик
@NetDeveloperDiary6.7K подп.
1.7Kпросмотров
25.5%от подписчиков
19 марта 2026 г.
statsScore: 1.9K
День 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
1.7K
просмотров
3693
символов
Нет
эмодзи
Нет
медиа

Другие посты @NetDeveloperDiary

Все посты канала →
День 2605. #ЗаметкиНаПолях 5 Малоизвестных Функций C#, Котор — @NetDeveloperDiary | PostSniper