Обложка канала

.NET Разработчик

Опытный разработчик не так давно зашёл в .Net и поставил цель получить сертификат Microsoft. Свой ежедневный прогресс он описывает на канале .Net Разработчик. Заметки об изученном материале, советы по повышению производительности и поддержке мотивации, ин

.NET Разработчик

3 года назад
Открыть в
День 1645. #ЗаметкиНаПолях Scrutor в .NET Сегодня рассмотрим библиотеку Scrutor, варианты её использования и что она предлагает для упрощения внедрения зависимостей, а также о реализации сквозных задач с использованием шаблона декоратора. Пакет Scrutor улучшает код внедрения зависимостей, предоставляя набор расширений для встроенного контейнера зависимостей .NET, которые добавляют поддержку сканирования готовых сборок и декорирования типов. Использование Scrutor для сканирования сборки Scrutor помогает упростить наш код внедрения зависимостей за счёт динамического поиска типов внутри сборок и их регистрации во время выполнения. Используя сканирование сборки, мы можем частично автоматизировать наш код регистрации зависимостей. Кроме того, мы можем использовать сканирование сборки для создания расширяемых систем. С помощью сканирования мы можем создать программу, способную находить и загружать дополнительные модули во время выполнения.
builder.Services.Scan(s => s
  .FromCallingAssembly()
  .AddClasses(c =>
   с.InNamespaces("MyApp.Services"))
  .AsImplementedInterfaces()
);

Здесь мы вызываем метод расширения Scan() который выполнит сканирование сборки (в данном случае - той, из которой он вызван) и выберет сервисы для регистрации на основе предоставленного нами селектора (в данном случае из пространства имён "MyApp.Services"). Наконец, мы регистрируем выбранные нами типы в качестве подстановки для всех интерфейсов, которые они реализуют, вызывая AsImplementedInterfaces(), т.к. обычно наши зависимости представляют собой интерфейсы (типа IUserService), а не классы напрямую. Используя широкий спектр методов расширения, которые предоставляет Scrutor, мы можем очень точно определить сервисы, которые мы хотим зарегистрировать, например, из другой сборки (библиотеки классов):
builder.Services.Scan(s => s
  .FromAssemblyOf<ICustomerService>()
  .AddClasses(c =>
   c.AssignableTo<ICustomerService>())
  .AsMatchingInterface());

Здесь мы просим Scrutor сканировать сборку, в которой находится интерфейс ICustomerService, используя метод расширения FromAssemblyOf<ICustomerService>(). Затем среди всех реализаций в этой сборке мы выбираем только те, которые могут быть назначены ICustomerService. Работа с обобщёнными типами Если мы хотим добавить реализацию обобщённого типа, то вместо обобщённой реализации метода AssignableTo, мы можем использовать метод с аргументом типа:
…
.AddClasses(c => 
 c.AssignableTo(typeof(IService<>)))
…

Указание времени жизни зависимостей Мы можем использовать спецификаторы времени жизни зависимостей:
builder.Services.Scan(s => s
  …
  .WithTransientLifetime()
);
Или соответственно WithScopedLifetime() и WithSingletonLifetime(). Обработка нескольких реализаций Стратегия регистрации — это то, как Scrutor обрабатывает случаи, когда для одного и того же интерфейса существует несколько реализаций:
builder.Services.Scan(s => s
  …
  .UsingRegistrationStrategy(RegistrationStrategy.Skip)
  .AsImplementedInterfaces()
);
В этом коде, используя метод UsingRegistrationStrategy() с параметром RegistrationStrategy.Skip, мы указываем Scrutor игнорировать дополнительные реализации любого интерфейса после регистрации первой. Другие варианты: - RegistrationStrategy.Append - добавляет новую регистрацию для существующих сервисов. - RegistrationStrategy.Throw - выдаёт ошибку при попытке зарегистрировать существующий сервис. Окончание следует… Источник: https://code-maze.com/dotnet-dependency-injection-with-scrutor/