Зарегистрировать коллекцию сервисов в MVC Core DI - PullRequest
0 голосов
/ 22 ноября 2018

У меня есть простой класс со стратегиями.

 public class LinkQualifier : ILinkQualifier
    {
        private readonly IEnumerable<IQualifier> _qualifiers;

        public LinkQualifier(IEnumerable<IQualifier> qualifiers)
        {
            _qualifiers = qualifiers;
        }

        public IQualifier Qualify(Uri uri)
        {
            return _qualifiers.FirstOrDefault(q => q.CanQualify(uri));
        }


    }

Как я могу зарегистрировать его в основном контейнере DI MVC?Я изобрел что-то вроде этого:

services.AddTransient<ILinkQualifier, LinkQualifier>((ctx =>
            {
                var qualifiers = new List<IQualifier> {...};
                return new LinkQualifier(qialifiers);
            }));

Но это выглядит плохо ... Есть ли лучшее решение?

Ответы [ 2 ]

0 голосов
/ 22 ноября 2018

Я собираюсь сделать предположение, что IEnumerable<IQualifier> может исходить из чего-то другого, чем сгенерированный / построенный список.
В этом случае вы можете создать интерфейс и реализацию, которая возвращает IEnumerable<IQualifier>

public interface IQualifiersProvider
{
    IEnumerable<IQualifier> GetQualifiers();
}

public class QualifiersProvider : IQualifiersProvider
{
    //from db / whatever
    public IEnumerable<IQualifier> GetQualifiers()
    {
        return new [] {
            new Qualifier(),
            new Qualifier(),
        }
    }
}

Измените LinkQualifier на зависимость от IQualifiersProvider

public class LinkQualifier : ILinkQualifier
{
    private readonly IEnumerable<IQualifier> _qualifiers;

    public LinkQualifier(IQualifiersProvider qualifiersProvider)
    {
        _qualifiers = qualifiersProvider.GetQualifiers();
    }

    public IQualifier Qualify(Uri uri)
    {
        return _qualifiers.FirstOrDefault(q => q.CanQualify(uri));
    }
}

Теперь зарегистрируйте их отдельно

services.AddTransient<IQualifiersProvider, QualifiersProvider>();
services.AddTransient<ILinkQualifier, LinkQualifier>();
0 голосов
/ 22 ноября 2018

Зарегистрируйте несколько реализаций с помощью ServiceCollection.

Зависимость IEnumerable<IQualifier> будет распознана контейнером DI и пройдет все зарегистрированные реализации.

services.AddTransient<IQualifier, QualifierOne>();
services.AddTransient<IQualifier, QualifierTwo>();
services.AddTransient<IQualifier, QualifierThree>();

services.AddTransient<ILinkQualifier, LinkQualifier>();

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

Ссылка Внедрение зависимостей ядра ASP.NET - регистрация нескольких реализаций интерфейса

...