Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Manual tenant switching without default middleware support in Finbuckle.MultiTenant #900

Open
buituansonHE172207 opened this issue Nov 11, 2024 · 2 comments
Labels

Comments

@buituansonHE172207
Copy link

I would like to know if there is a plan or approach for manually changing the current tenant in Finbuckle.MultiTenant without relying on the default middleware. This could be helpful in scenarios where more flexibility is needed, especially in non-HTTP contexts such as background jobs, scheduled tasks, or long-running processes, where tenant context might need to be set or switched programmatically rather than automatically by middleware.

Example use cases include:

Setting the tenant for background jobs managed by job schedulers (e.g., Hangfire or Quartz.NET).
Switching tenants within custom workflows or batch processing, where tenant needs to be controlled manually.
This feature would help to achieve a smoother integration in various job and background processing scenarios.

@AndrewTriesToCode
Copy link
Contributor

AndrewTriesToCode commented Nov 11, 2024

Hi this is possible now by using the TenantResolver class. The middleware simply wraps this class usage for web app scenarios but the other scenarios like you listed can use it directly as well. It is intended to work with DI and have the strategies and stores injected so it can use them. It can work with the generic host just as easily as the web host.

I have improved the documentation on this for the .NET 9 release later this week but I will try to add some samples.

@buituansonHE172207
Copy link
Author

Thank you for your support!

Here is my current approach for setting up the tenant context within a job:

public async Task ExecuteJobForTenant(string? tenantIdentifier, IJobExecutionStrategy jobExecutionStrategy)
{
    using var scope = serviceScopeFactory.CreateScope();
    var serviceProvider = scope.ServiceProvider;
    ArgumentNullException.ThrowIfNull(tenantIdentifier);
    var tenantInfo = await tenantService.GetByIdentifierAsync(tenantIdentifier);
    if (tenantInfo != null)
    {
        var mtcSetter = serviceProvider.GetRequiredService<IMultiTenantContextSetter>();
        var resolver = serviceProvider.GetRequiredService<ITenantResolver>();
        var httpContextAccessor = serviceProvider.GetRequiredService<IHttpContextAccessor>();
        var httpContext = httpContextAccessor.HttpContext ?? new DefaultHttpContext();

        // Setting the CampusCode header for tenant identification
        httpContext.Request.Headers.Append("CampusCode", tenantInfo.Identifier);
        var mtContext = await resolver.ResolveAsync(httpContext);
        mtcSetter.MultiTenantContext = mtContext;

        // Execute the job with the tenant context
        await jobExecutionStrategy.ExecuteJobForTenantAsync(serviceProvider);
    }
}

Could you please provide feedback on this approach? I’d like to know if this is a recommended way to manually set up the tenant context for non-HTTP contexts like background jobs, and if there are any potential improvements or best practices that could enhance stability and performance.

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

2 participants