Effects Composition¶
The Tenancy module integrates with the effects system through CorrelationContext. While there is no standalone [EffectsModule] for tenancy, the tenant ID flows automatically through all effect pipelines via the ambient context.
How Tenant Flows Through Effects¶
Every Eff<RT, T> pipeline inherits the current CorrelationContext, which includes TenantId. This means:
TenantMiddlewaresetsCorrelationContext.Current.TenantIdat the start of the request- All downstream effect methods see the tenant automatically
- Outbound HTTP calls propagate
ds-tenant-idheader viaCorrelationDelegatingHandler
Reading Tenant in Effects¶
Access the current tenant through CorrelationContext:
var tenantScopedOperation =
from tenant in liftEff<AppRuntime, string?>(rt =>
CorrelationContext.Current?.TenantId)
from _ in Guard<AppRuntime>(tenant is not null,
Error.New(400, "No tenant context"))
from data in AppStore.TenantData.GetByTenantId<AppRuntime>(new TenantId(tenant!))
select data;
Tenant-Scoped Queries¶
DataStore implementations automatically scope queries by tenant when TenantId is present in CorrelationContext:
// This query is automatically tenant-scoped — no manual filtering needed
var getOrders =
from orders in AppStore.Orders.GetAll<AppRuntime>()
select orders;
// Returns only orders for the current tenant
TypedId¶
TenantId uses a custom TypedId profile:
The tenant profile uses BackingType.String since tenant identifiers are often external strings (e.g., from JWT claims or headers).