Table of Contents

Namespace Trellis.Mediator

Classes

ActorCommandHandler<TCommand, TResponse>

Supplies the dispatch's authorized actor to command business logic.

ActorQueryHandler<TQuery, TResponse>

Supplies the dispatch's authorized actor to query business logic.

ActorResourceCommandHandler<TCommand, TResource, TResponse>

Supplies the checked actor and directly authorized resource to command business logic.

ActorResourceQueryHandler<TQuery, TResource, TResponse>

Supplies the checked actor and directly authorized resource to query business logic.

ActorResourceViaCommandHandler<TCommand, TLeaf, TOwner, TResponse>

Supplies the checked actor and loaded leaf, not its authorization owners, to command business logic.

ActorResourceViaQueryHandler<TQuery, TLeaf, TOwner, TResponse>

Supplies the checked actor and loaded leaf, not its authorization owners, to query business logic.

AuthorizationBehavior<TMessage, TResponse>

Pipeline behavior that checks the current actor has all permissions declared in RequiredPermissions. Short-circuits with Error.Forbidden if any permission is missing.

AuthorizationContextBehavior<TMessage, TResponse>

Establishes an isolated authorization snapshot and lifetime for each Mediator dispatch.

DomainEventDispatchBehavior<TMessage, TResponse>

Pipeline behavior that dispatches domain events accumulated on the success-value aggregate after the command handler returns. Events fire after any inner TransactionalCommandBehavior commits, so handlers see committed state.

DomainEventDispatchReport

The per-handler outcome of a dispatch performed through PublishReportingAsync(IDomainEvent, IReadOnlySet<string>?, CancellationToken).

DomainEventDispatchServiceCollectionExtensions

Extension methods for registering Trellis.Mediator domain-event dispatch.

DomainEventHandlerCascadedException

Thrown by the domain event dispatch behaviors and helper when the aggregate's pending-event list no longer matches the entry snapshot at the end of dispatch. The validation is strict: length must match AND each position must be reference-equal to the snapshot, so any handler-caused mutation (raising new events, clearing via AcceptChanges, replacing, reordering) triggers this exception. Handlers MUST be side-effect-only. In the multi-aggregate tracked-dispatch variant, every aggregate in the snapshot is validated and offenders are reported together in Offenders.

Note: this exception fires AFTER the inner TransactionalCommandBehavior commits. The database state is durable, but the dispatch-stage response is failure-shaped. Consumers retrying the same command will hit "already committed" semantics; durable at-least-once dispatch requires the outbox pattern (planned, not shipped).

DomainEventHandlerFailure

A single handler's failure during a reported domain-event dispatch.

DomainEventPublisherExtensions

Extension methods over IDomainEventPublisher for call sites that need to dispatch an aggregate's UncommittedEvents() manually (outside the DomainEventDispatchBehavior<TMessage, TResponse> pipeline).

ExceptionBehavior<TMessage, TResponse>

Pipeline behavior that catches unhandled exceptions from handlers and converts them to Error.Unexpected failures. This is a safety net — handlers should not throw, but if they do, this prevents unhandled exceptions from escaping the mediator pipeline.

IntegrationEnvelope

The consume-side envelope handed to IInboxDispatcher: a stable MessageId plus the deserialized IIntegrationEvent. Only MessageId and Event are load-bearing; the remaining members are optional lineage / observability metadata and never participate in deduplication.

IntegrationEventDispatchServiceCollectionExtensions

Extension methods for registering Trellis.Mediator integration-event publishing.

IntegrationEventNameMap

A bidirectional map between an integration event's stable wire name (see IntegrationEventNameAttribute) and its local CLR type — the contract a broker transport serializes through so producer and consumer never exchange assembly-qualified type names.

IntegrationMessageContext

Carries the current inbound integration message's lineage across asynchronous handler work. Applications can also supply an explicit business correlation id without deriving one from a trace.

LoggingBehavior<TMessage, TResponse>

Pipeline behavior that logs command/query execution with duration and Result outcome. The per-message start entry is logged at Debug; the matching end entry is at Debug on success, Information for expected caller/domain failures (validation, authentication, authorization, not-found, conflict, rate-limited, invariant-violation, gone, and aggregates whose inner errors are all expected), and Warning for unexpected, dependency, or opaque transport failures. Cross-cutting per-message observability noise belongs at Debug, not Information; consumers who want per-call timing in production raise the level via "Trellis.Mediator": "Debug" in their logging configuration.

MediatorTraceProviderBuilderExtensions

Extension methods for configuring OpenTelemetry tracing for the Trellis mediator pipeline.

OutboundIntegrationMessage

The publish-side counterpart of IntegrationEnvelope: the integration event to publish together with the stable MessageId a transport must carry verbatim onto the wire.

ResolvedAuthorizationHop

Describes a single hop in an indirect authorization chain.

ResolvedAuthorizationPath

Pre-computed navigation path from a leaf resource to an owner resource for indirect (multi-hop) resource authorization. Constructed at registration time (either by the assembly-scanning resolver or by an explicit registration helper) and passed to ResourceAuthorizationViaBehavior<TMessage, TLeaf, TOwner, TResponse>.

ResolvedAuthorizationPathHolder<TMessage, TLeaf, TOwner, TResponse>

Closed-generic carrier for a ResolvedAuthorizationPath registered per via-authorized command. Used so DI naturally disambiguates the path per command (each closed generic is a distinct service type) and so ResourceAuthorizationViaBehavior<TMessage, TLeaf, TOwner, TResponse> can be registered as a TYPED descriptor (not a factory descriptor), letting ServiceCollectionExtensions's relocator recognize it by ImplementationType alone.

ResourceAuthorizationBehavior<TMessage, TResource, TResponse>

Pipeline behavior that loads a resource and performs resource-based authorization before the handler runs. Registered as scoped so the injected IServiceProvider is the request-scoped provider, allowing correct resolution of scoped dependencies.

ResourceAuthorizationOptions

Configures the resource-authorization pipeline's failure-exposure policy on a per-resource basis. Register via services.AddResourceAuthorization(o => o.HideExistence<Incident>()) or through the TrellisServiceBuilder.UseResourceAuthorization(o => ...) composition slot.

ResourceAuthorizationPathResolver

Resolves a ResolvedAuthorizationPath from a leaf resource type to an owner resource type by walking the entity graph defined by IIdentifyRelatedResource<TRelated, TId> and IIdentifyRelatedResources<TRelated, TId> declarations on candidate entity types.

ResourceAuthorizationViaBehavior<TMessage, TLeaf, TOwner, TResponse>

Pipeline behavior that performs indirect (multi-hop) resource-based authorization. The command identifies a leaf resource via the existing IResourceLoader<TMessage, TResource> infrastructure and declares its final authorization target via IAuthorizeResourceVia<TOwner>; this behavior walks the pre-resolved ResolvedAuthorizationPath from leaf to owner and invokes the command's Authorize(Actor, IReadOnlyList<TOwner>) method against the final list of owners.

ServiceCollectionExtensions

Extension methods for registering Trellis.Mediator pipeline behaviors.

TracingBehavior<TMessage, TResponse>

Pipeline behavior that creates an OpenTelemetry Activity for each command/query. Tags the activity with Result status and error details on failure.

TrackedAggregateDomainEventDispatchBehavior<TMessage, TResponse>

Opt-in pipeline behavior that, after a successful command, dispatches domain events from every aggregate the unit of work tracked at commit time — regardless of the command's response shape. Companion to DomainEventDispatchBehavior<TMessage, TResponse>, which only fires for Result<TAggregate> responses.

TrackedAggregateDomainEventDispatchServiceCollectionExtensions

Opt-in registration for TrackedAggregateDomainEventDispatchBehavior<TMessage, TResponse>.

TransactionalCommandBehaviorServiceCollectionExtensions

Registration for the TransactionalCommandBehavior<TMessage, TResponse> pipeline behavior, independent of any persistence adapter. Any adapter that registers an Trellis.IUnitOfWork (the shipped EF Core adapter does this in AddTrellisUnitOfWork<TContext>()) can call AddTransactionalCommandBehavior(IServiceCollection) to install the standard commit pipeline.

TransactionalCommandBehavior<TMessage, TResponse>

Pipeline behavior that automatically commits staged changes after a successful command handler.

The behavior wraps each command invocation in an Trellis.IUnitOfWork.BeginScope() scope, runs the handler (which stages changes via repositories), then calls CommitAsync(CancellationToken) if the handler returned success. If the handler returned a failure Result<TValue>, no commit occurs and the staged changes are discarded when the underlying store/context is disposed.

Persist-on-failure outcomes. If the response implements IPersistOnFailure and the per-instance flag is true (the canonical producer is FailAfterCommit<TValue>(Error)), the commit step also runs even though the result is a failure. This enables the worker-handler pattern of persisting a permanently_failed state row alongside the failure outcome. On commit failure for a persist-on-failure outcome, the commit error replaces the handler error in the returned result.

This behavior is constrained to Mediator.ICommand<TResponse> messages — queries are not wrapped and incur no overhead.

Atomicity: the unit of work persists all staged changes within a single handler atomically (the shipped EF Core adapter does so through the DbContext's implicit transaction). Cross-aggregate operations that share the same unit of work are automatically transactional.

Nested-command semantics. When a command handler dispatches another command via IMediator, the inner command flows through the same pipeline and the inner TransactionalCommandBehavior<TMessage, TResponse> opens a nested Trellis.IUnitOfWork.BeginScope(). The inner CommitAsync(CancellationToken) defers (returns success without touching the store) until the outermost scope unwinds. This prevents a successful inner command from committing a partially-completed outer command's staged changes. Caveat: if the inner command returns a failure but the outer handler ignores it and returns success, the outer's commit will persist any changes the inner staged before failing — handlers that need to discard inner failures' staged work must detach the affected entities themselves. Every Trellis.IUnitOfWork implementation must implement Trellis.IUnitOfWork.BeginScope() with depth-aware semantics; the shipped EF Core unit of work does this with an internal depth counter.

TrellisMediatorTelemetryOptions

Operator-tunable redaction settings for the Trellis mediator pipeline's logging and tracing behaviors. Resolved from DI; if not registered, the behaviors fall back to the safe-by-default values exposed by this type's parameterless constructor.

ValidationBehavior<TMessage, TResponse>

Unified validation stage of the Trellis Mediator pipeline. Runs the compile-time IValidate contract (when the message implements it) and every IMessageValidator<TMessage> registered for TMessage in DI, aggregates all Error.InvalidInput failures into a single response failure, and short-circuits the pipeline before the handler is invoked.

Structs

CascadeOffender

Identifies an aggregate whose pending-event list changed during domain event dispatch.

HopLoadResult

Result of loading a single related resource at one ID during a hop walk.

Interfaces

IDomainEventHandler<TEvent>

Handles a domain event raised by an IAggregate. Implementations are resolved via DI by the DomainEventDispatchBehavior<TMessage, TResponse> after a successful command and invoked once per matching event.

IDomainEventPublisher

Publishes a single IDomainEvent by resolving and invoking all IDomainEventHandler<TEvent> registrations for the event's runtime type.

IInboxDispatcher

The inbound entry point for idempotent integration-event consumption. A transport adapter — a broker consumer or the in-process path — builds an IntegrationEnvelope and calls DispatchAsync(IntegrationEnvelope, CancellationToken); the dispatcher deduplicates on (ConsumerId, MessageId) so the event's integration-event handlers' side effects commit exactly once (effectively-once), together with the dedup record.

IIntegrationEventCollector

Collects IIntegrationEvent instances produced while a domain-event handler (the translator) handles a domain event, so the transactional outbox can capture them durably and the relay can publish them after the producing work is committed. This is the translation seam: a domain-event handler observes a domain event and adds the integration events that describe the same fact in contract terms.

IIntegrationEventHandler<TEvent>

Handles an IIntegrationEvent - the in-process consumer side of the external contract. Implementations are resolved via DI and invoked once per matching event by the default IIntegrationEventPublisher.

IIntegrationEventPublisher

Publishes a single IIntegrationEvent, together with the stable message identity a transport must carry onto the wire, to its consumers. The transactional outbox relay resolves this contract to deliver integration events durably after the producing transaction commits.

IMessageValidator<TMessage>

Contributes a validation step to the unified validation stage of the Trellis Mediator pipeline (ValidationBehavior<TMessage, TResponse>).

IReportingDomainEventPublisher

Publishes a domain event and reports each handler's outcome instead of swallowing failures.

IValidate

Marker interface for commands/queries that can self-validate before reaching the handler. Implement on command/query records to enable the ValidationBehavior<TMessage, TResponse>.

Enums

AuthFailureExposurePolicy

Controls how the resource-authorization pipeline surfaces authorization-related failures to clients. The choice is per-resource (configured via ResourceAuthorizationOptions) because different resources warrant different existence-disclosure trade-offs even within a single application.

InboxDispatchOutcome

The outcome of dispatching one message through DispatchAsync(IntegrationEnvelope, CancellationToken): whether this call committed the handlers' side effects, or the message was already processed so this call committed nothing. Both outcomes mean the message is durably accounted for, so a pull consumer can safely advance its checkpoint on either; the distinction exists for metrics, logging, and overlap / anti-join bookkeeping.