Eternet.Mediator.Generator
7.4.0
Prefix Reserved
See the version list below for details.
dotnet add package Eternet.Mediator.Generator --version 7.4.0
NuGet\Install-Package Eternet.Mediator.Generator -Version 7.4.0
<PackageReference Include="Eternet.Mediator.Generator" Version="7.4.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="Eternet.Mediator.Generator" Version="7.4.0" />
<PackageReference Include="Eternet.Mediator.Generator"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add Eternet.Mediator.Generator --version 7.4.0
#r "nuget: Eternet.Mediator.Generator, 7.4.0"
#:package Eternet.Mediator.Generator@7.4.0
#addin nuget:?package=Eternet.Mediator.Generator&version=7.4.0
#tool nuget:?package=Eternet.Mediator.Generator&version=7.4.0
Eternet.Mediator.Generator
Source generator package for production pipeline execution in Eternet.Mediator.
Installation
dotnet add package Eternet.Mediator.Generator
Use it as an analyzer/source-generator package in projects that generate mediator pipelines.
Runtime Ownership
Each assembly that declares [GenerateExecutePipeline<...>] must reference a pipeline generator so it can emit its own
pipeline executors and StepsResults partials. In multi-assembly hosts, only one assembly should own the concrete
mediator runtime (Mediator.Mediator, MediatorOptions, and AddMediator).
Prefer Eternet.Mediator.Pipeline.Generator for assemblies that need pipeline generation but should not own the
runtime:
dotnet add package Eternet.Mediator.Pipeline.Generator
It emits pipeline executors, StepsResults, and pipeline registration extensions only.
The host/runtime owner can then include the pipeline-only assembly in TargetAssemblies:
services.AddMediator(options =>
{
options.TargetAssemblies =
[
typeof(HostServiceRegistration).Assembly,
typeof(FeatureFromPipelineOnlyAssembly).Assembly
];
});
TargetAssemblies controls handler discovery for the generated runtime. It does not generate pipeline code for other
assemblies.
Static Dispatch
The generated Mediator dispatches every discovered message without reflection. Each Send, CreateStream and
Publish(object) overload looks up the exact runtime type of the message once and calls a typed method that resolves
the closed IRequestHandler<TMessage, TResponse> (or command, query, stream handler) and the closed
IPipelineBehavior<TMessage, TResponse> list from DI. Behaviors run in registration order; generated
[GenerateExecutePipeline] executors implement ITerminalPipelineBehavior and always run last, right before the
handler. With no behaviors, the handler is called directly.
Messages whose handlers the generator did not discover (handlers outside TargetAssemblies, open generic handlers, or
handlers registered by hand in DI) go through one isolated fallback that resolves them by runtime type, as earlier
versions did. Set the MSBuild property below to turn that fallback into a MissingMessageHandlerException, which
removes the last reflection from the generated runtime:
<PropertyGroup>
<EternetMediatorStrictDispatch>true</EternetMediatorStrictDispatch>
</PropertyGroup>
Publish<TNotification>(notification) keeps resolving INotificationHandler<TNotification> by the static type.
Call-site interceptors
The generator also intercepts sender.Send(...), sender.CreateStream(...) and publisher.Publish(...) calls made
through ISender, IMediator or IPublisher when all of these hold:
- the message has a generated handler in this compilation (so
TargetAssembliesapplies, and messages handled by HTTP clients or other services are left alone); - for
SendandCreateStream, the static type of the argument is its runtime type (anewexpression, a sealed class or a struct) and the requested response is the handler response, without covariance; - the call is not inside an expression tree.
When the receiver is the generated Mediator, the interceptor calls its typed SendRequest_<Message> (or command,
query, stream, PublishNotification_<Message>) method directly. The IL at the call site then names the handler and the
closed behaviors of that message, and the runtime type lookup is skipped. Any other receiver (test doubles, HTTP clients,
decorators) goes through Mediator.MediatorInterceptorFallback, which makes the original interface call, so mocks see
the same calls as before.
The package .props adds Mediator.Interceptors to InterceptorsNamespaces; the generator emits nothing when the
namespace is not enabled (for example, a project that references the generator project directly without the .props).
To turn interception off:
<PropertyGroup>
<EternetMediatorInterceptors>false</EternetMediatorInterceptors>
</PropertyGroup>
Step Execution Policies
[UseStepExecutionPolicy<TPolicy>] marks a step whose raw Handle(...) call is wrapped by a policy-managed input and
outcome flow while the generated executor keeps owning retry, exception recovery, duration measurement, publication, and
stateful resume.
Use it when the pipeline graph should keep the business step visible, but the app needs reusable per-step decisions such as skip rules, input construction, and mapping raw responses or failures to a domain outcome.
The step signature must expose exactly one domain input plus an optional CancellationToken:
[UseStepExecutionPolicy<RunExternalSyncPolicy>]
public sealed class RunExternalSyncAsync
{
public Task<ExternalSyncResponse> Handle(
ExternalSyncInput input,
CancellationToken cancellationToken)
{
return client.RunAsync(input, cancellationToken);
}
}
The policy implements the exact closed contract:
public sealed class RunExternalSyncPolicy
: IStepExecutionPolicy<
RunSynchronization.Request,
ExternalSyncInput,
ExternalSyncResponse,
ScheduledSynchronizationOutcome>
{
public ValueTask<StepExecutionInput<ExternalSyncInput>> BuildInputAsync(
RunSynchronization.Request request,
StepExecutionPolicyContext context,
CancellationToken cancellationToken)
{
return request.Options.Enabled
? ValueTask.FromResult(StepExecutionInput<ExternalSyncInput>.Execute(new(request.ExecutionId)))
: ValueTask.FromResult(StepExecutionInput<ExternalSyncInput>.Skip("External sync is disabled."));
}
public ValueTask<ScheduledSynchronizationOutcome> MapAsync(
RunSynchronization.Request request,
StepExecutionResult<ExternalSyncResponse> result,
StepExecutionPolicyContext context,
CancellationToken cancellationToken)
{
return ValueTask.FromResult(ScheduledSynchronizationOutcome.From(result));
}
}
For policy-managed steps, StepsResults publishes the mapped TStepOutcome, not the raw TStepResponse. Stateful
pipelines persist the mapped outcome and reuse it on resume when ReExecutionPolicy = ReuseIfAvailable.
Diagnostics:
EM105: unsupported policy-managed step signature.EM106: policy type does not implement the exact closedIStepExecutionPolicy<...>contract.
Full consumer guide: ../doc/StepExecutionPolicies.md.
Breaking Changes in 3.0.0
Eternet.Mediator.Generator 3.0.0 emits code against the new generated runtime facade.
- Generated executors no longer declare or pass
ScopedStates. - Generated code uses an assembly-local generated runtime helper backed by
GeneratedBindingRuntime. request.StepsResultsis the supported developer-facing result model.- Applications or tests that still depend on public
ScopedStates-based generated output must stay on2.xuntil migrated.
Migration guide:
../docs/scoped-states-breaking-change-v3.md
Learn more about Target Frameworks and .NET Standard.
This package has no dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 7.5.0 | 0 | 11/3/2026 |
| 7.4.0 | 0 | 11/3/2026 |
| 7.3.1 | 41 | 11/2/2026 |
| 7.3.0 | 57 | 11/2/2026 |
| 7.2.0 | 63 | 10/30/2026 |
| 7.1.0 | 110 | 10/17/2026 |
| 7.0.0 | 822 | 10/17/2026 |
| 6.1.0 | 99 | 10/16/2026 |
| 6.0.0 | 95 | 10/15/2026 |
| 5.1.0 | 91 | 10/14/2026 |
| 5.0.1 | 154 | 10/10/2026 |
| 5.0.0 | 98 | 10/10/2026 |
| 4.0.0 | 121 | 10/6/2026 |
| 3.6.0 | 479 | 9/21/2026 |
| 3.5.1 | 109 | 9/15/2026 |
| 3.5.0 | 117 | 9/14/2026 |
| 3.4.16 | 111 | 9/11/2026 |
| 3.4.15 | 147 | 9/7/2026 |
| 3.4.14 | 119 | 9/3/2026 |
| 3.4.13 | 269 | 8/29/2026 |
Generated endpoints and HTTP clients support explicit FromBody direct root payload contracts.