Hangfire - Multi tenant, ASP.NET Core - Resolving the correct tenant

前端 未结 1 1391
我寻月下人不归
我寻月下人不归 2020-12-16 04:59

I got a SaaS project that needs the use Hangfire. We already implemented the requirements to identify a tenant.

Architecture

  • Persisten
相关标签:
1条回答
  • 2020-12-16 05:24

    First, you need to be able to set the TenantId in your TenantCurrentService. Then, you can rely on filters :

    client side (where you enqueue jobs)

    public class ClientTenantFilter : IClientFilter
    {
            public void OnCreating(CreatingContext filterContext)
            {
               if (filterContext == null) throw new ArgumentNullException(nameof(filterContext));
    
                filterContext.SetJobParameter("TenantId", TenantCurrentService.TenantId);
            }
    }
    

    and server side (where the job is dequeued).

    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;
        }
    }
    

    The server filter can be declared when you configure your server through an IJobFilterProvider:

            var options = new BackgroundJobServerOptions
            {
                Queues = ...,
                FilterProvider = new ServerFilterProvider()
            };
            app.UseHangfireServer(storage, options, ...);
    

    where ServerFilterProvider is :

    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),
                       };
        }
    }
    

    The client filter can be declared when you instantiate a BackgroundJobClient

    var client = new BackgroundJobClient(storage, new BackgroundJobFactory(new ClientFilterProvider());
    

    where ClientFilterProvider behaves as ServerFilterProvider, delivering client filter

    A difficulty may be to have the TenantCurrentService available in the filters. I guess this should be achievable by injecting factories in the FilterProviders and chain it to the filters.

    I hope this will help.

    0 讨论(0)
提交回复
热议问题