Merge remote-tracking branch 'origin/release/3.8.0' into release/3.8.0

This commit is contained in:
Sipke Schoorstra 2026-08-03 02:08:23 +02:00
commit e59a0f1721
No known key found for this signature in database
GPG key ID: 5C10502B28A4268F
3 changed files with 54 additions and 3 deletions

View file

@ -37,7 +37,14 @@ public class TenantResolutionMiddleware(RequestDelegate next, ITenantScopeFactor
await using var tenantScope = tenantScopeFactory.CreateScope(tenant);
var originalServiceProvider = context.RequestServices;
context.RequestServices = tenantScope.ServiceProvider;
await next(context);
context.RequestServices = originalServiceProvider;
try
{
await next(context);
}
finally
{
context.RequestServices = originalServiceProvider;
}
}
}
}

View file

@ -7,6 +7,7 @@
<ItemGroup>
<ProjectReference Include="..\..\..\src\common\Elsa.Testing.Shared\Elsa.Testing.Shared.csproj" />
<ProjectReference Include="..\..\..\src\modules\Elsa.Tenants.AspNetCore\Elsa.Tenants.AspNetCore.csproj" />
<ProjectReference Include="..\..\..\src\modules\Elsa.Tenants\Elsa.Tenants.csproj" />
<ProjectReference Include="..\..\..\src\modules\Elsa.Common\Elsa.Common.csproj" />
</ItemGroup>

View file

@ -0,0 +1,43 @@
using Elsa.Common.Multitenancy;
using Elsa.Tenants.AspNetCore.Middleware;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using NSubstitute;
namespace Elsa.Tenants.UnitTests.Middleware;
public class TenantResolutionMiddlewareTests
{
[Fact]
public async Task InvokeAsync_WhenNextThrows_RestoresOriginalRequestServices()
{
await using var rootProvider = new ServiceCollection()
.AddScoped(_ => new ScopedProbe())
.BuildServiceProvider();
await using var originalRequestScope = rootProvider.CreateAsyncScope();
var originalRequestServices = originalRequestScope.ServiceProvider;
var context = new DefaultHttpContext { RequestServices = originalRequestServices };
var expectedException = new InvalidOperationException("Downstream failure");
var tenantScopeFactory = new DefaultTenantScopeFactory(
new DefaultTenantAccessor(),
rootProvider.GetRequiredService<IServiceScopeFactory>());
var middleware = new TenantResolutionMiddleware(
_ => Task.FromException(expectedException),
tenantScopeFactory);
var tenantResolverPipelineInvoker = Substitute.For<ITenantResolverPipelineInvoker>();
tenantResolverPipelineInvoker
.InvokePipelineAsync(Arg.Any<CancellationToken>())
.Returns(Task.FromResult<Tenant?>(null));
var exception = await Assert.ThrowsAsync<InvalidOperationException>(
() => middleware.InvokeAsync(context, tenantResolverPipelineInvoker));
Assert.Same(expectedException, exception);
Assert.Same(originalRequestServices, context.RequestServices);
Assert.NotNull(context.RequestServices.GetRequiredService<ScopedProbe>());
}
private sealed class ScopedProbe
{
}
}