繁体   English   中英

如何在.Net Core中的应用程序class上使用依赖注入来实现实体框架池化上下文以实现多租户?

[英]How to use Dependency Injection on a application class in .Net Core for an Entity Framework Pooled Context to achieve multi-tenant implementation?

我已经实现了一个使用 .Net Core 3.1 和 Entity Framework 的应用程序。

该应用程序使用实体框架 dbcontext 池,利用 Pomelo mysql ef 库。

services.AddDbContextPool<myDbContext>(
            options => options
                .UseMySql(Configuration.GetConnectionString("DefaultConnection"),
                mysqlOptions =>
                {
                    mysqlOptions.MaxBatchSize(MySqlConfig.EfBatchSize);
                    mysqlOptions.EnableRetryOnFailure();
                    if (MySqlConfig.EfRetryOnFailure > 0)
                    {
                        mysqlOptions.EnableRetryOnFailure(MySqlConfig.EfRetryOnFailure, TimeSpan.FromSeconds(5), null);
                    }
                }
        ).UseLoggerFactory(consoleLoggerFactory));

需要注意的是AddDbContextPool的使用请参见此处: https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.entityframeworkservicecollectionextensions.adddbcontextpool?view=efcore-3.1

使用上下文池时,您的应用程序需要有一个带有 DbContextOptions 的构造函数。 即:我不能将另一个 object (在我的情况下,我需要一个应用程序服务 class 来列出允许的租户,以及其他与索赔相关的逻辑......)到这个 class 中,否则不能使用池。

public myDbContext(DbContextOptions<myDbContext> options)
            : base(options)
        {
        }

另一个需要注意的是,我使用 HttpContextAccessor 来访问经过身份验证的用户的声明,其中包括允许该用户访问的租户,当然也可以通过依赖注入访问。 身份验证和声明是通过 openid 检索的,最终将声明作为 Active Directory 组检索,因此我没有也不会在数据库中包含此信息,因为它源自 Active Directory...

这个问题的实质是,我怎样才能访问我的 DbContext 中的 HttpContext 以便在我的应用程序中实现多租户支持的全局过滤器,并且仍然使用 DB 上下文池。

我可以通过删除池来实现这一点,并通过构造函数正常使用 DI,但这不是我所追求的。 我需要保持池化,并实现多租户功能。

首先,如果您的租户位于不同的数据库中,则 DbContext 池根本不起作用。 打开 DbContext 后,它会连接到单个数据库。 这是一个次要的性能特征,所以它不是一个很大的损失。

如果您正在设置查询过滤器,您可以通过简单地不直接将 DbContext 注入控制器来使其工作,而是注入预先配置的服务包。 这还允许您集中代码以重新配置当前租户的 DbContext。 例如:

public class ServiceContext 
{
    MyDbContext dbContext;
    HttpContext httpContext;
    IConfiguration config;
    public ServiceContext(MyDbContext dbContext, IHttpContextAccessor httpContextAccessor, IConfiguration config)
    {
        this.dbContext = dbContext;
        this.httpContext = httpContextAccessor.HttpContext;
        this.config = config;
        //use the httpContext to reconfigure the DbContext for single-tenant access
    }

    public HttpContext HttpContext { get => httpContext; set => throw new NotImplementedException(); }
    public MyDbContext DbContext { get => dbContext; }
    public IConfiguration Configuration { get => config; }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM