如何在IServiceCollection.Configure()中使用IServiceProvider

时间:2018-02-12 17:05:04

标签: asp.net-core dependency-injection .net-core

是否可以在IServiceProvider内使用IServiceCollection.Configure()

我认为Configure()没有超载来接受Func<IServiceProvider, T&gt;之类的内容。其他扩展方法(如IServiceCollection.AddScoped())的重载方式接受Func<IServiceProvider, T>

我想做这样的事情:

public static void AddCommandHandlers(this IServiceCollection services, Assembly assembly)
{
    // CommandExecutor has a dependency on CommandHandlerFactory
    services.AddScoped<CommandExecutor>();

    services.Configure<CommandHandlerFactory>(myFactory =>
    {
        // How can I use IServiceProvider here? Example scenario:

        foreach(Type t in FindHandlers(assembly))
            myFactory.AddHandler(serviceProvider => serviceProvider.GetService(t));
    });
}

目标是能够为不同的程序集调用AddCommandHandlers扩展方法多次,并将找到的处理程序(使用DI)附加到同一CommandHandlerFactoryCommandExecutor可以调用工厂来获取处理程序。

或许还有另一种方式?

任何帮助表示赞赏。
感谢。

2 个答案:

答案 0 :(得分:1)

您可以随时在IServiceCollection上调用BuildServiceProvider()扩展方法来构建ServiceProvider。你需要  Microsoft.Extensions.DependencyInjection

显然只会包含已添加到集合中的所有服务,因此您需要按正确顺序调用内容。

Particle System

答案 1 :(得分:1)

您可以在一个公共接口上注册每个命令处理程序:

foreach(Type t in FindHandlers(assembly))
    services.AddScoped<ICommandHandler>(t);

然后,您可以使工厂接受IEnumerable<ICommandHandler>作为构造函数参数。

public class CommandHandlerFactory
{
    public CommandHandlerFactory(IEnumerable<ICommandHandler> handlers)
    {
        foreach(var handler in handlers)
           AddHandler(handler);
    }

    // The rest of the factory
}

或者,如果您不能更改构造函数,则可以这样设置工厂:

services.AddSingleton(serviceProvider =>
{
    var factory = new CommandHandlerFactory();

    foreach(var handler in serviceProvider.GetServices<ICommandHandler>();
        factory.AddHandler(handler);

    return factory;

});