中间件向 DI 容器或服务添加新的依赖项

我正在编写一个中间件(也许我想要一个范围服务??),我想我的计划是拥有某种多租户场景。

例如,如果我有 2 个响应此服务的域:

  • www.domain1.com

  • www.domain2.com

我想在请求启动时捕获请求,查看正在使用的主机名,然后通过依赖注入将其他一些对象设置为可用于管道中的所有内容。

看来中间件应该是实现这一目标的正确方法,但不确定如何执行最后一步。

我的选择似乎是:

中间件

  • 注册Singleton服务来访问数据库

  • 尽早注册成为第一个捕获请求的中间件。

    • 分析请求对象并构建自定义配置对象

    • 将自定义配置作为范围对象添加到 DI 容器以供其他服务使用

服务

  • 注册Singleton服务来访问数据库

  • 为 IHttpContextAccessor 注册 Singleton 服务

  • 注册范围?服务——相当于中间件

    • 分析请求对象并构建自定义配置对象

    • 将自定义对象注册为 DI 容器中的新作用域对象

我的假设是服务能够注册自定义范围的对象,因为它仍在ConfigureServicesstartup.cs的方法中

然而,对于中间件来说,它是通过ConfigureDI 容器已经构建完成的方法来初始化的?


守候你守候我
浏览 104回答 1
1回答

ITMISS

您可以使用工厂重载来AddScoped实现您希望每个租户/请求都不同的服务。这是一个例子:services.AddScoped<IServiceForTenant>(sp =>{    var httpContextAccessor = sp.GetRequiredService<IHttpContextAccessor>();    var serviceForTenant = new ServiceForTenant();    // TODO: Use httpContextAcccessor.HttpContext to configure serviceForTenant.    return serviceForTenant;});对于进入 ASP.NET Core 应用程序的每个请求,上面的代码将在您首次IServiceForTenant在控制器中发出请求时运行。此时,您的代码可以读取IHttpContextAccessor.HttpContext并做出所需的任何决策,以便为IServiceForTenant. 然后,该相同的实例将用于请求的其余部分(即管道的更上游)。传入的参数AddScoped是Func<IServiceProvider, T>. 您需要在这里提供某种委托,这可以通过多种方式之一来完成。以下是一些示例:您可以将调用包装到其自己的扩展方法中,如下所示:public static void AddServiceForTenant(this IServiceCollection services){    services.AddScoped<IServiceForTenant>(sp =>    {        // ...    });}在ConfigureServices:services.AddServiceForTenant();使用带有方法的类static:public static class ServiceForTenantFactory{    public static ITenantForService Create(IServiceProvider sp)    {        // ...    }}在ConfigureServices:services.AddScoped(ServiceForTenantFactory.Create);使用带有实例方法的类:public class ServiceForTenantFactory{    public ITenantForService Create(HttpContext httpContext)    {        // ...    }}在ConfigureServices:services.AddScoped(sp =>{    var httpContextAccessor = sp.GetRequiredService<IHttpContextAccessor>();    var serviceForTenantFactory = new ServiceForTenantFactory(); // Or use DI.    return serviceForTenantFactory.Create(httpContextAccessor.HttpContext);});最后一个选项是最灵活的,因为您甚至可以ServiceForTenantFactory从 DI 解析自身,并且它可以有自己的依赖项等。另请注意,Create这里直接采用HttpContext(作为示例)。正如我已经说过的,还有比所示的三个更多的选项,但这应该是一个很好的使用基础。
打开App,查看更多内容
随时随地看视频慕课网APP