asp.net-core – 如何在IServiceCollection.Configure()中使用IServiceProvider

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

我看到Configure()上没有重载接受像Func< IServiceProvider,T>这样的东西.其他扩展方法,如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)附加到同一个CommandHandlerFactory,以便CommandExecutor可以只调用工厂来获取处理程序.

或许还有另一种方式?

任何帮助赞赏.
谢谢.

最佳答案 您可以针对公共接口注册每个命令处理程序:

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;

});
点赞