ITenantPropagator interface
Namespace: Tenantry.Pro · Package: Tenantry.Pro · API reference
An extension point: for code that extends the package, such as another package that builds on it. An application rarely needs it.
Carries the tenant into jobs and messages, with tenant ids as text, so a transport needs no tenant key type. Tenantry.Pro's Hangfire, MassTransit, Quartz.NET and Rebus integrations use it; use it to carry the tenant over another bus or job library. UsePro registers it as a singleton.
On the sending side, put ITenantPropagator.CurrentTenantId in the job's or message's headers, under HeaderName. On the receiving side, pass that header to ITenantPropagator.ResolveAsync with the integration's TenantPropagationOptions, then run the work inside ITenantPropagator.Use. A carried tenant id is trusted as it is: only let producers you control send work. For the integrations' options and startup check too, write an ITenantPropagationAdapter.
var tenant = await propagator.ResolveAsync(message.Headers["tenantry-tenant-id"], options, "Kafka message", message.Id, ct);
if (tenant.Skip)
return;
using (propagator.Use(tenant)) await handler.HandleAsync(message, ct); ```
```csharp
[EditorBrowsable(EditorBrowsableState.Advanced)]
public interface ITenantPropagatorProperties
CurrentTenantId
The current tenant's id, as text, or null when no tenant is current.
string? CurrentTenantId { get; }Value: string
Methods
GetTenantIdsAsync(CancellationToken)
The ids, as text, of every tenant in the store that ValidateTenantActivity allows, for work scheduled once for each tenant.
ValueTask<IReadOnlyList<string>> GetTenantIdsAsync(CancellationToken cancellationToken = default)Parameters:
cancellationTokenCancellationToken: Cancels the store read.
Returns: ValueTask<IReadOnlyList<string>>
Resolve(string?, TenantPropagationOptions, string, object?)
As ITenantPropagator.ResolveAsync, blocking on the tenant lookup, for a host whose filters are synchronous.
PropagatedTenant Resolve(string? tenantId, TenantPropagationOptions options, string carrier, object? carrierId)Parameters:
tenantIdstring: The tenant id the job or message carries, or null.optionsTenantPropagationOptions: The integration's policy.carrierstring: What carries the tenant, for log messages and errors, such asKafka message.carrierIdobject: The job's or message's id, for log messages and errors.
Returns: PropagatedTenant: The tenant to make current with ITenantPropagator.Use, none, or that the work must not run.
Exceptions:
TenantNotResolvedException: The policy that applies isTenantPropagationBehavior.Reject.
ResolveAsync(string?, TenantPropagationOptions, string, object?, CancellationToken)
Finds the tenant a job or message carries, applying options when it carries none, an id that is not valid, a tenant the store does not have, or one ValidateTenantActivity refuses.
ValueTask<PropagatedTenant> ResolveAsync(string? tenantId, TenantPropagationOptions options, string carrier, object? carrierId, CancellationToken cancellationToken = default)Parameters:
tenantIdstring: The tenant id the job or message carries, or null.optionsTenantPropagationOptions: The integration's policy.carrierstring: What carries the tenant, for log messages and errors, such asKafka message.carrierIdobject: The job's or message's id, for log messages and errors.cancellationTokenCancellationToken: Cancels the tenant lookup.
Returns: ValueTask<PropagatedTenant>: The tenant to make current with ITenantPropagator.Use, none, or that the work must not run.
Exceptions:
TenantNotResolvedException: The policy that applies isTenantPropagationBehavior.Reject.
Use(PropagatedTenant)
Makes the resolved tenant current until the returned handle is disposed, tags the current activity with tenant.id and opens a log scope with TenantId. For PropagatedTenant.WithoutTenant, makes no tenant current instead, so the work does not run as a tenant that was current around it.
IDisposable Use(PropagatedTenant tenant)Parameters:
tenantPropagatedTenant: WhatITenantPropagator.ResolveAsyncreturned, unless it isPropagatedTenant.Skipped.
Returns: IDisposable: A handle that restores the tenant that was current before.
Exceptions:
ArgumentException:tenantisPropagatedTenant.Skipped, or its tenant is not anITenantDescriptor<TKey>of the application's tenant key type.
Call it in the method that runs the work: the tenant is ambient, and an async method's changes to it end when that method returns.
ITenantPropagationAdapter interface
An extension point: for code that extends the package, such as another package that builds on it.
ITenantProvisioner<TKey> interface
Provisions a new tenant: runs every ITenantProvisioningStep<TKey>tenantry-pro-itenantprovisioningstep.md for it, in order, and reports each step's outcome.