发布
社区首页 >问答首页 >Hangfire -多租户,ASP.NET核心-解析正确的租户

Hangfire -多租户,ASP.NET核心-解析正确的租户
EN

Stack Overflow用户
提问于 2019-08-07 12:38:43
回答 1查看 4.9K关注 0票数 13

我有一个需要使用Hangfire的SaaS项目。我们已经实现了识别租户的要求。

体系结构

  • 持久化层
    • 每个租户都有自己的数据库

  • .NET核心
    • 我们已经有了一个服务TenantCurrentService,它从源主机名、查询字符串等列表中返回租户的ID。
    • 我们已经有了一个实体框架的DbContextFactory,它为客户端返回一个带有正确连接字符串的DB上下文
    • 我们目前正在使用ASP.NET核心DI (如果这有帮助的话愿意改变)

  • 汉火
    • 使用单个存储(例如: Postgresql),无论租户数量如何
    • 在适当的容器/ServiceCollection中执行作业,因此我们检索正确的数据库、正确的设置等。

问题

我正在尝试将一个TenantId标记为一个作业,从TenantCurrentService (它是一个作用域服务)中检索。

然后执行作业时,我们需要从作业中检索TenantId并将其存储在HangfireContext中,这样TenantCurrentService就知道从Hangfire检索到的TenantId了。然后,我们的应用层将能够从我们的DbContextFactory连接到正确的数据库。

电流状态

  • 目前,我们已经能够使用tenantId存储从服务中检索到的IClientFilter
  • 如何从.GetRequiredService().IdentifyTenant(tenantId) (负责检索已保存的作业参数)检索当前的ASP.NET核心DI ServiceScope,以便调用IServerFilter

有关于这件事的好文章吗?或者你们能提供的任何建议吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-08-07 14:19:54

首先,您需要能够在您的TenantId中设置TenantCurrentService。然后,您可以依赖于过滤器:

客户端(您在其中登记作业)

代码语言:javascript
代码运行次数:0
复制
public class ClientTenantFilter : IClientFilter
{
        public void OnCreating(CreatingContext filterContext)
        {
           if (filterContext == null) throw new ArgumentNullException(nameof(filterContext));

            filterContext.SetJobParameter("TenantId", TenantCurrentService.TenantId);
        }
}

和服务器端(作业退出队列的地方)。

代码语言:javascript
代码运行次数:0
复制
public class ServerTenantFilter : IServerFilter
{
    public void OnPerforming(PerformingContext filterContext)
    {
      if (filterContext == null) throw new ArgumentNullException(nameof(filterContext));

      var tenantId = filterContext.GetJobParameter<string>("TenantId");
      TenantCurrentService.TenantId = tenantId;
    }
}

当您通过IJobFilterProvider配置服务器时,可以声明服务器筛选器

代码语言:javascript
代码运行次数:0
复制
        var options = new BackgroundJobServerOptions
        {
            Queues = ...,
            FilterProvider = new ServerFilterProvider()
        };
        app.UseHangfireServer(storage, options, ...);

其中ServerFilterProvider是:

代码语言:javascript
代码运行次数:0
复制
public class ServerFilterProvider : IJobFilterProvider
{
    public IEnumerable<JobFilter> GetFilters(Job job)
    {
        return new JobFilter[]
                   {
                       new JobFilter(new CaptureCultureAttribute(), JobFilterScope.Global, null),
                       new JobFilter(new ServerTenantFilter (), JobFilterScope.Global,  null),
                   };
    }
}

可以在实例化BackgroundJobClient时声明客户端筛选器。

代码语言:javascript
代码运行次数:0
复制
var client = new BackgroundJobClient(storage, new BackgroundJobFactory(new ClientFilterProvider());

其中ClientFilterProvider作为ServerFilterProvider运行,传递客户端筛选器

一个困难可能是让TenantCurrentService在过滤器中可用。我想这应该可以通过在FilterProviders中注入工厂并将其链接到过滤器来实现。

我希望这能帮上忙。

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57394712

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档