using Elsa.Common.Multitenancy;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Http;
namespace Elsa.Tenants.AspNetCore.Middleware;
///
/// Middleware to initialize the tenant for each incoming HTTP request.
///
[UsedImplicitly]
public class TenantResolutionMiddleware(RequestDelegate next, ITenantScopeFactory tenantScopeFactory)
{
///
/// Invokes the middleware to ensure the tenant is initialized.
///
/// The current HTTP context.
///
public async Task InvokeAsync(HttpContext context, ITenantResolverPipelineInvoker tenantResolverPipelineInvoker)
{
var tenant = await tenantResolverPipelineInvoker.InvokePipelineAsync();
if (tenant != null)
{
var tenantPrefix = tenant.GetRoutePrefix();
if (!string.IsNullOrWhiteSpace(tenantPrefix))
{
var tenantPath = $"/{tenantPrefix}";
if (context.Request.Path.StartsWithSegments(tenantPath))
{
context.Request.PathBase = tenantPath;
context.Request.Path = context.Request.Path.Value![tenantPath.Length..];
}
}
}
await using var tenantScope = tenantScopeFactory.CreateScope(tenant);
var originalServiceProvider = context.RequestServices;
context.RequestServices = tenantScope.ServiceProvider;
try
{
await next(context);
}
finally
{
context.RequestServices = originalServiceProvider;
}
}
}