Внедрение Зависимостей в ASP.NET Core. Продолжение (3/4)
Начало
Продолжение
Регистрация нескольких сервисов
Если в методе
ConfigureServices используется несколько регистраций для одного интерфейса, то последняя из них имеет приоритет.services.AddTransient<IMessageSender, EmailSender>();Здесь в приложении будет использован
services.AddTransient<IMessageSender, SMSSender>();
SMSSender.Чтобы избежать случайной «перезаписи» зарегистрированных сервисов, можно использовать соответствующий
TryAdd… метод (например, TryAddTransient). Тогда реализация будет добавлена, только если она ещё не была зарегистрирована ранее.Важно отметить, что без использования
TryAdd… зарегистрированы будут оба сервиса, но лишь последняя реализация будет использована при обнаружении сервиса.Иногда нужно явно перезаписать предыдущую регистрацию. Тогда используется метод
Replace, принимающий дескриптор сервиса:services.Replace(Чтобы удалить все регистрации сервисов для определённого интерфейса, используется метод
new ServiceDescriptor(typeof(IMessageSender),
typeof(SMSSender), ServiceLifetime.Transient)
);
RemoveAll:services.RemoveAll<IMessageSender>();Использовать эти методы придётся редко. Например, чтобы предоставить свою реализацию одного из сервисов сторонней библиотеки.
Зачем же контейнер DI регистрирует несколько реализаций? Это может пригодиться, когда вам нужно, например, зарегистрировать несколько отправителей сообщений, валидаторов данных или бизнес-правил, которые должны будут применены одно за другим. В этом случае в конструктор зависимого класса внедряется коллекция сервисов:
public class Notifier {
IEnumerable<IMessageSender> _senders;
public Notifier(
IEnumerable<IMessageSender> senders) {
_senders = senders;
}
public void SendMessage() {
foreach (var s in _senders) {
// обработка каждого отправителя
}
}
}
Таким образом, если мы хотим добавить, скажем, отправку через пуш-уведомления, нам нужно только добавить реализацию и зарегистрировать её в контейнере DI. Это одно из ограничений стандартного контейнера. Другие, более продвинутые, позволяют автоматически сканировать сборку и добавлять все реализации интерфейса.При регистрации нескольких реализаций может быть нежелательно регистрировать одинаковые реализации, что обычными методами не проверяется. В нашем случае, если случайно зарегистрировать
SMSSender дважды, сообщение по смс будет отправлено 2 раза. Тогда можно использовать метод TryAddEnumerable, принимающий коллекцию дескрипторов сервисов:services.TryAddEnumerable(new[]В этом случае будет зарегистрирована только одна реализация
{
new ServiceDescriptor(typeof(IMessageSender),
typeof(EmailSender), ServiceLifetime.Transient),
new ServiceDescriptor(typeof(IMessageSender),
typeof(SMSSender), ServiceLifetime.Transient),
new ServiceDescriptor(typeof(IMessageSender),
typeof(SMSSender), ServiceLifetime.Transient)
});
SMSSender.Окончание следует…
Источник: https://app.pluralsight.com/library/courses/aspdotnet-core-dependency-injection/