首页 > 解决方案 > 如何在.net core 3中强制Func作为强类型依赖注入?

问题描述

我在一个库中公开了处理消息代理的所有机制,客户端需要使用扩展方法来使用它,我需要它提供一组处理程序实现IMessageHandler将处理每个订阅通道的接口。它可以工作,但我的原型只需要通过Func我想要强类型的依赖注入,以强制客户端提供预期的接口依赖注入。

这是消息处理的接口:

public interface IMessageHandler
{
    void HandleMessageAsync(object sender, MyEventArgs e);
}

我在 lib 中的扩展方法的原型:

public static IServiceCollection UseTheSuperMessageBroker(
    this IServiceCollection services,
    IConfiguration config,
    params Func<IServiceCollection>[] handlers)

然后客户端可以像这样使用扩展方法:

services.UseTheSuperMessageBroker(Configuration,
handlers: new Func<IServiceCollection>[] {
    () => services.AddSingleton<IMessageHandler, myMessageHandler1>(),
    () => services.AddSingleton<IMessageHandler, myMessageHandler2>()
});

但是没有什么能阻止客户端提供任何与接口无关的依赖注入IMessageHandler,实际上最后一个参数让我们这样做:

services.UseTheSuperMessageBroker(
    Configuration,
    handlers: new Func<IServiceCollection>[] {
        () => services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(),
        () => services.AddSingleton(typeof(IMongoRepository<>), typeof(MongoRepository<>))
    });

这是编译但不是预期的。

那么有什么机制可以用来强制Func使用仅与接口相关的依赖注入IMessageHandler

标签: c#asp.net-coregenericsdependency-injectionfunc

解决方案


不,没有办法阻止这种情况,因为你只是IServiceCollection直接使用。事实上,这里的代码甚至没有使用 lambda 局部变量,而是包含方法的局部变量,即services. 本质上,只要存在这样做的手段,任何事情都可以在这里完成ConfigureServices

如果这是您的要求,那么简单地获取IMessageHandler类型的集合然后在方法中注册它们会好得多,而不是使用 Func.

public static IServiceCollection UseTheSuperMessageBroker(
    this IServiceCollection services,
    IConfiguration config,
    params Type[] handlers)

services.UseTheSuperMessageBroker(Configuration,
    handlers: new[] {
        typeof(myMessageHandler1),
        typeof(myMessageHandler2)
    });

然后,在该方法中:

foreach (var handler in handlers)
{
    services.AddSingleton(typeof(IMessageHandler), handler);
}

从技术上讲,这不会阻止他们添加未实现的类型IMessageHandler,但是因为您要IMessageHandler显式绑定,所以如果他们这样做,它将失败。


推荐阅读