IRoute

The contract every train fulfils: take an input, produce an output or fail. Train<TInput, TReturn> implements it, and IServiceTrain<TIn, TOut> extends it, so code that only needs to run something can depend on IRoute without knowing it is a train.

Signature

namespace Trax.Core.Route;
 
public interface IRoute<in TIn, TOut>
{
    Task<TOut> Run(TIn input, CancellationToken cancellationToken = default);
}
ParameterTypeDescription
inputTInThe input to run with
cancellationTokenCancellationTokenCancels the run

Returns: Task<TOut>, the output. A failure is thrown, as from Run.

Where it appears

TypeRelationship
Train<TInput, TReturn>Implements IRoute<TInput, TReturn>
IServiceTrain<TIn, TOut>Extends IRoute<TIn, TOut> and IDisposable, and adds Metadata
A service train's own interfaceExtends IServiceTrain<TIn, TOut>, and so IRoute

The registration helpers are named after it (AddScopedTraxRoute and its siblings) because they register any route, train or junction.

Example

using Trax.Core.Route;
 
public class OrderEndpoint(IRoute<CreateOrderInput, OrderResult> createOrder)
{
    public Task<OrderResult> Handle(CreateOrderInput input, CancellationToken ct) =>
        createOrder.Run(input, ct);
}

The container has no registration for IRoute<,> itself: register the train under its own interface and resolve that, or forward it (services.AddTransient<IRoute<CreateOrderInput, OrderResult>>(sp => sp.GetRequiredService<ICreateOrderTrain>())).

Package

dotnet add package Trax.Core