Train Registration

Extension methods for registering Trax.Core trains with the .NET DI container. These methods wrap standard AddScoped/AddTransient/AddSingleton and add [Inject] property injection support.

Signatures

Generic Overloads

public static IServiceCollection AddScopedTraxRoute<TService, TImplementation>(
    this IServiceCollection services
) where TService : class where TImplementation : class, TService
 
public static IServiceCollection AddTransientTraxRoute<TService, TImplementation>(
    this IServiceCollection services
) where TService : class where TImplementation : class, TService
 
public static IServiceCollection AddSingletonTraxRoute<TService, TImplementation>(
    this IServiceCollection services
) where TService : class where TImplementation : class, TService

Non-Generic Overloads

public static IServiceCollection AddScopedTraxRoute(
    this IServiceCollection services,
    Type serviceInterface,
    Type serviceImplementation
)
 
public static IServiceCollection AddTransientTraxRoute(
    this IServiceCollection services,
    Type serviceInterface,
    Type serviceImplementation
)
 
public static IServiceCollection AddSingletonTraxRoute(
    this IServiceCollection services,
    Type serviceInterface,
    Type serviceImplementation
)

Type Parameters

Type ParameterConstraintDescription
TServiceclassThe service interface type (e.g., IMyTrain)
TImplementationclass, TServiceThe implementation type (e.g., MyTrain)

Returns

IServiceCollection, for continued chaining.

Example

services.AddTransientTraxRoute<ICreateOrderTrain, CreateOrderTrain>();
services.AddScopedTraxRoute<IProcessPaymentTrain, ProcessPaymentTrain>();

What It Does

  1. Registers TImplementation with the DI container at the specified lifetime.
  2. Registers TService with a factory that:
    • Resolves TImplementation from the container
    • Calls InjectProperties() to set all [Inject]-attributed properties on the instance
    • Sets CanonicalName to TService's FullName (the interface name). This is used as the train's canonical identifier in metadata, work queue entries, and subscription matching. See Canonical Train Naming.
    • Returns the fully-initialized instance

When to Use

Use these methods when your train class (or its base class) uses [Inject] properties. For example, ServiceTrain<TIn, TOut> has:

[Inject] public IEffectRunner? EffectRunner { get; set; }
[Inject] public ILogger<ServiceTrain<TIn, TOut>>? Logger { get; set; }
[Inject] public IJunctionEffectRunner? JunctionEffectRunner { get; set; }

Without AddTraxRoute, these properties would remain null after DI resolution.

Remarks

  • If your trains are discovered via AddMediator, you don't need to register them manually. The bus handles registration automatically.
  • These methods are primarily useful for trains registered outside of assembly scanning, or when you need explicit control over the DI lifetime.
  • A train instance is one run at a time. It carries the state of the run in progress: its metadata row, its effect runner and that runner's data context. Each call to Run records its own metadata row, so a scoped instance run twice in one scope records two runs, the second with a new ExternalId unless you set one. Do not share an instance between concurrent callers.
  • AddSingletonTraxRoute refuses a service train with an InvalidOperationException at registration, because one instance for the whole process would be shared by every run in it. Register trains scoped or transient. The singleton overloads remain for junctions and other routes that carry no per-run state.
  • The non-generic overloads accept Type parameters for dynamic/reflection-based registration scenarios.

SDK Reference

AddMediator | Route and Junction Registration | Inject