Skip to content

Repository files navigation

Trax.Effect

BuildNuGet VersionNuGet Downloads.NETLicense: MITLast CommitcodecovDocs

Effect system for Trax.Core. Upgrades a bare locomotive into a full commercial train service with journey logging, station services, and dependency injection.

The Trax Stack

Trax is a layered framework split across several repos. You can stop at whatever layer solves your problem. You are here: Trax.Effect.

RepoAdds
Trax.CorePipelines, junctions, railway error propagation
Trax.EffectExecution logging, DI, pluggable storage
Trax.MediatorDecoupled dispatch via TrainBus
Trax.SchedulerCron schedules, retries, dead-letter queues
Trax.ApiGraphQL API for remote access
Trax.DashboardBlazor monitoring UI
Trax.Clitrax-cli project scaffolding tool
Trax.SamplesSample apps and a dotnet new template

Full documentation: traxsharp.net/docs.

What This Does

Trax.Core gives you Train<TIn, TOut>: a locomotive that carries cargo through a sequence of stops. That's enough for pure logic, but production services need to know what ran, when it departed, whether it arrived, what it was carrying, and what went wrong if it derailed.

Trax.Effect adds the ServiceTrain<TIn, TOut> base class, a full commercial train service that wraps every journey with:

  • Journey logging: a persistent metadata record for each run (state, timing, cargo in, cargo out, derailment details)
  • Station services: pluggable effect providers that fire during execution (data persistence, logging, parameter serialization, progress tracking)
  • DI integration: stops are resolved from IServiceProvider, so you get constructor injection out of the box

Installation

dotnet add package Trax.Effect

For data persistence, pick a storage depot:

# PostgreSQL (production)
dotnet add package Trax.Effect.Data.Postgres
# In-memory (testing / prototyping)
dotnet add package Trax.Effect.Data.InMemory

Optional station services:

dotnet add package Trax.Effect.Provider.Json # Debug logging of train state
dotnet add package Trax.Effect.Provider.Parameter # Serialize cargo to the journey log

Setup

Register station services in your IServiceCollection:

builder.Services.AddTrax(trax =>trax.AddEffects(effects =>effects.UsePostgres(connectionString).SaveTrainParameters().AddJunctionLogger(serializeJunctionData:true).AddJunctionProgress()));

For development or tests, swap Postgres for in-memory:

builder.Services.AddTrax(trax =>trax.AddEffects(effects =>effects.UseInMemory().AddJson()));

Usage

Inherit from ServiceTrain instead of Train:

publicinterfaceICreateUserTrain:IServiceTrain<CreateUserRequest,User>{}publicclassCreateUserTrain:ServiceTrain<CreateUserRequest,User>,ICreateUserTrain{protectedoverrideasyncTask<Either<Exception,User>>RunInternal(CreateUserRequestinput)=>Activate(input).Chain<ValidateEmailJunction>().Chain<CreateUserInDatabaseJunction>().Chain<SendWelcomeEmailJunction>().Resolve();}

The route syntax is identical to Train. The difference is what happens around it. ServiceTrain automatically opens a journey log when the train departs, updates it when it arrives, persists effect data at each station, and records the derailment details if any stop fails.

Junctions work the same way, with full DI:

publicclassCreateUserInDatabaseJunction(AppDbContextdb):Junction<CreateUserRequest,User>{publicoverrideasyncTask<User>Run(CreateUserRequestinput){varuser=newUser{Email=input.Email,Name=input.Name};db.Users.Add(user);awaitdb.SaveChangesAsync();returnuser;}}

Journey Lifecycle

Every ServiceTrain journey transitions through:

Pending → InProgress → Completed
→ Failed
→ Cancelled

Think of it as: the train is boarding (Pending), in transit (InProgress), and then either arrives (Completed), derails (Failed), or is pulled from service (Cancelled). These states are persisted in the journey log and queryable through the data layer.

Station Services

ServicePackageWhat it does
PostgresTrax.Effect.Data.PostgresPersists journey logs and execution data to PostgreSQL
InMemoryTrax.Effect.Data.InMemoryIn-memory store for tests and local dev
JsonTrax.Effect.Provider.JsonLogs state transitions as JSON for debugging
ParameterTrax.Effect.Provider.ParameterSerializes train cargo (inputs/outputs) into the journey log
JunctionLoggerBuilt-inLogs each junction's execution with optional cargo serialization
JunctionProgressBuilt-inTracks per-junction progress and checks for cancellation signals

Station services compose, so enable as many as you need:

effects.UsePostgres(connectionString).AddJson().SaveTrainParameters().AddJunctionLogger(serializeJunctionData:true).AddJunctionProgress();

DI Registration Helpers

Register your trains as scoped services with proper interface mapping:

builder.Services.AddScopedTraxRoute<ICreateUserTrain,CreateUserTrain>();builder.Services.AddTransientTraxRoute<IProcessOrderTrain,ProcessOrderTrain>();

Or use AddMediator (from Trax.Mediator) to auto-register all trains in an assembly.

Next Layer

When you need decoupled dispatch (callers don't know which train handles a request), move up to Trax.Mediator.

License

MIT

Trademark & Brand Notice

Trax is an open-source .NET framework provided by TraxSharp. This project is an independent community effort and is not affiliated with, sponsored by, or endorsed by the Utah Transit Authority, Trax Retail, or any other entity using the "Trax" name in other industries.

About

Resources

Security policy

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages