Добавить зависимость на основе некоторых условий в AspNetCore - PullRequest
0 голосов
/ 10 апреля 2019

Я хочу добавить зависимость, если выполняется какое-то условие, но для проверки условия мне нужно использовать IServiceProvider. Есть ли хороший способ сделать это?

Вот мой код, но наверняка он не работает должным образом по многим причинам, но это то, чего я достиг до сих пор:

Также я не хочу перестраивать IServiceCollection дважды!

public static IServiceCollection AddWithCondition<TInterface, TImplementation>(
    this IServiceCollection collection, 
    Func<IServiceProvider, bool> validateFunc,
    ServiceLifetime lifetime,
    Func<IServiceProvider, TImplementation> factory)
    where TImplementation :  class
{ 
    collection.Add(new ServiceDescriptor(typeof(TInterface), p => validateFunc(p) ? factory(p) : default(TImplementation), lifetime));
    var descriptorToRemove = collection.FirstOrDefault(d => d.ServiceType == typeof(TInterface) && d.ImplementationInstance == default);
    if (descriptorToRemove != null)
        collection.Remove(descriptorToRemove);
    return collection;
}

1 Ответ

0 голосов
/ 11 апреля 2019

Вы, кажется, применяете доменную логику на этапе запуска / настройки приложения, который, как указано в комментариях, пахнет кодом. Я предлагаю вам реорганизовать ваше приложение, чтобы использовать фабричный шаблон для создания экземпляров запрошенных сервисов. Фабрика может использовать инъекцию зависимостей для выполнения условной логики. Например:

Услуги:

public interface IService { }

public class FooService : IService { }

// And more implementations of IService...

Сервисная фабрика:

public interface IServiceFactory
{
    IEnumerable<IService> GetServices();
}

public class ServiceFactory : IServiceFactory
{
    public ServiceFactory(MyWebservice myWebservice) { }

    public IEnumerable<IService> GetServices()
    {
        // Use MyWebservice to conditionally create the desired IService instances
        // or use any other type of logic.
    }
}

После добавления IServiceFactory в свой контейнер внедрения зависимостей вы можете внедрить его и использовать для разрешения экземпляров IService:

public class SomeController
{
    public SomeController(IServiceFactory serviceFactory) { }

    public IActionResult Get()
    {
        var services = _serviceFactory.GetServices();
        // Do something with the created IService instances...
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...