Stratara.Mediator
3.1.6
dotnet add package Stratara.Mediator --version 3.1.6
NuGet\Install-Package Stratara.Mediator -Version 3.1.6
<PackageReference Include="Stratara.Mediator" Version="3.1.6" />
<PackageVersion Include="Stratara.Mediator" Version="3.1.6" />
<PackageReference Include="Stratara.Mediator" />
paket add Stratara.Mediator --version 3.1.6
#r "nuget: Stratara.Mediator, 3.1.6"
#:package Stratara.Mediator@3.1.6
#addin nuget:?package=Stratara.Mediator&version=3.1.6
#tool nuget:?package=Stratara.Mediator&version=3.1.6
Stratara.Mediator
License: MIT.
In-process mediator with DI-resolved handlers and pipeline behaviors. Drop-in replacement for MediatR-style routing without the runtime cost of MethodInfo.Invoke — uses a typed wrapper cache and direct DI dispatch.
Quick start
services.AddMediator()
.AddCommandHandlersFromAssemblyContaining<Program>()
.AddQueryHandlersFromAssemblyContaining<Program>()
.AddPipelineBehaviorWithResult(typeof(LoggingBehavior<,>))
.AddPipelineBehavior(typeof(LoggingBehavior<>));
// Optional: wrap in authorization decorator
services.AddAuthorizingMediator<MyAuthorizationProvider>();
What's in the box
IMediator.HandleAsync<TResult>(IRequest<TResult>, CancellationToken)— routes queries and commands-with-result toIQueryHandler<TRequest, TResult>through any registeredIPipelineBehavior<TRequest, TResult>chain.IMediator.HandleAsync<TRequest>(TRequest, CancellationToken)— routes void commands toICommandHandler<TRequest>through any registeredIPipelineBehavior<TRequest>chain.AuthorizingMediatordecorator — checks[RequireRole]attributes on the request type viaIAuthorizationProviderbefore delegating to the inner mediator.BucketLockPool— concurrency primitive that serialisesIAggregateScopedCommanddispatch per bucket id. Used by message-bus consumers (e.g.Stratara.Infrastructure'sMediatorCommandWorker) to keep aggregate writes single-writer.
Pipeline behavior contract
Behaviors run outer-to-inner in DI registration order:
public sealed class LoggingBehavior<TRequest, TResult> : IPipelineBehavior<TRequest, TResult>
where TRequest : IRequest<TResult>
{
public async Task<TResult> HandleAsync(
TRequest request, Func<Task<TResult>> next, CancellationToken cancellationToken)
{
// before
var result = await next();
// after
return result;
}
}
Tenant isolation
AddStrataraTenantIsolation() registers a pipeline behavior that enforces tenant isolation at the
mediator entrance — before the handler runs — for any request that opts in by implementing the
ITenantScopedRequest marker. Requests that do not implement the marker pass through untouched.
public sealed record GetCustomerQuery(Guid CustomerId, Guid TenantId)
: IQuery<CustomerDto>, ITenantScopedRequest;
services
.AddStrataraValidation() // validation stays outermost
.AddStrataraTenantIsolation(); // then tenant isolation
The behavior compares the request's TenantId (the data owner) against the ambient session's
data-owner tenant (SessionContext.TenantId), not the actor tenant (SessionContext.ActorTenantId).
A request whose payload names a different tenant than the established session subject is rejected with
TenantAccessDeniedException (translated to HTTP 403 by AuthorizationExceptionMiddleware on ASP.NET
hosts; surfaced through the message-failure path on workers).
Default vs. strict mode
TenantIsolationMode.Default— enforces only the subject match. A privileged cross-tenant operation (actor tenant ≠ data-owner tenant) passes, because the calling endpoint is expected to have promoted the session's data-owner tenant to the target before dispatch.TenantIsolationMode.Strict— additionally routes every cross-tenant operation through anICrossTenantAuthorizer. Stratara registers a deny-all default (viaTryAdd), so strict mode rejects all cross-tenant access until you register your own authorizer that grants it:
services.AddStrataraTenantIsolation(o => o.Mode = TenantIsolationMode.Strict);
services.AddScoped<ICrossTenantAuthorizer, PlatformAdminCrossTenantAuthorizer>();
internal sealed class PlatformAdminCrossTenantAuthorizer(IHttpContextAccessor http)
: ICrossTenantAuthorizer
{
public ValueTask<bool> IsCrossTenantAllowedAsync(SessionContext session, CancellationToken ct) =>
ValueTask.FromResult(http.HttpContext?.User.IsInRole("PlatformAdmin") ?? false);
}
The behavior runs both in-process (queries via
IMediatorat the endpoint, whereHttpContextis available) and worker-side (commands dispatched through the outbox, where there is noHttpContext). AnICrossTenantAuthorizerthat needs request-role state should be applied on the in-process path; the worker path must base its decision on theSessionContextalone.
Dependencies
Stratara.Abstractions— forIMediator/IRequest/ICommand/IQuery/IPipelineBehaviorcontracts, plusITenantScopedRequest/ICrossTenantAuthorizer/TenantAccessDeniedException.Stratara.Diagnostics— log-event IDs for the tenant-isolation behavior.Microsoft.Extensions.DependencyInjection.Abstractions.Microsoft.Extensions.Logging.Abstractions.OpenTelemetry.Api— emits anActivityper dispatch under theStratara.Applicationsource.
No EF Core, no message bus, no event sourcing. Library-safe.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- JetBrains.Annotations (>= 2025.2.4)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.8)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.8)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.8)
- OpenTelemetry.Api (>= 1.15.3)
- Stratara.Abstractions (>= 3.1.6)
- Stratara.Diagnostics (>= 3.1.6)
NuGet packages (3)
Showing the top 3 NuGet packages that depend on Stratara.Mediator:
| Package | Downloads |
|---|---|
|
Stratara.Validation
Vendor-neutral request validation for the Stratara framework — a mediator pipeline behavior that runs IValidator<T> implementations before the handler and throws an aggregated StrataraValidationException on failure. No FluentValidation dependency; an optional adapter is shipped separately. |
|
|
Stratara.Outbox.RabbitMQ
Outbox-pattern command and event dispatch for the Stratara event-sourced stack — RabbitMQ IMessageBus implementation, retry worker, mediator command worker, and Redis-coordinated projection-replay state. Azure Service Bus support ships as the sibling Stratara.Outbox.AzureServiceBus package. |
|
|
Stratara.Infrastructure
Infrastructure glue for the Stratara framework — authorization decorators, configuration providers, and DI composition helpers that wire Mediator, Outbox, Identity, and EF Core into a hosted app. |
GitHub repositories
This package is not used by any popular GitHub repositories.
### Changed
- **License changed from FSL-1.1-MIT to the MIT License.** Stratara is now OSI-approved open
source — free for any use, including commercial, with no competition clause and no two-year
conversion delay. The previous Functional Source License (source-available, converting to MIT
two years after each release) has been replaced outright. Package metadata now declares the
SPDX expression `MIT` (`PackageLicenseExpression`), so nuget.org renders a standard clickable
MIT license label instead of an embedded custom-license file. The `LICENSE` file at the repo
root now contains the standard MIT text and is still bundled into every package. No code or API
changes accompany this — it is purely a licensing and metadata change. Previously published
versions (3.0.20 through 3.1.5) remain under the FSL terms they shipped with; this change applies
to all versions released from here on.