Getting Started
Trax requires net10.0:
<TargetFramework>net10.0</TargetFramework>If you're migrating from ChainSharp, see Migration Guide.
Pick the track that matches what you need:
Track 1: Core Only
Type-safe pipelines with no infrastructure. No database, no DI container, no ASP.NET required.
dotnet add package Trax.CoreDefine Junctions
public class ValidateEmailJunction : Junction<CreateUserRequest, Unit>
{
public override async Task<Unit> Run(CreateUserRequest input)
{
if (!IsValidEmail(input.Email))
throw new ValidationException("Invalid email format");
return Unit.Default;
}
private static bool IsValidEmail(string email)
=> new EmailAddressAttribute().IsValid(email);
}
public class FormatNameJunction : Junction<CreateUserRequest, FullName>
{
public override Task<FullName> Run(CreateUserRequest input)
=> Task.FromResult(new FullName($"{input.FirstName} {input.LastName}"));
}Define a Train
public class CreateUserTrain : Train<CreateUserRequest, FullName>
{
protected override async Task<Either<Exception, FullName>> RunInternal(CreateUserRequest input)
=> Activate(input)
.Chain<ValidateEmailJunction>()
.Chain<FormatNameJunction>()
.Resolve();
}Run It
var train = new CreateUserTrain();
var result = await train.RunEither(new CreateUserRequest
{
Email = "test@example.com",
FirstName = "Test",
LastName = "User"
});
result.Match(
Left: ex => Console.WriteLine($"Failed: {ex.Message}"),
Right: name => Console.WriteLine($"Created: {name}")
);Next: Core docs for Memory, the Analyzer, chain methods, and IDE extensions.
Track 2: Core + Effect
Add execution logging, DI, and persistent metadata. Every train run becomes a queryable record.
dotnet add package Trax.Core
dotnet add package Trax.Effect
dotnet add package Trax.Effect.Data.Postgres # or Trax.Effect.Data.InMemoryProgram.cs Setup
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddTrax(trax => trax
.AddEffects(effects => effects
.UsePostgres(builder.Configuration.GetConnectionString("TraxDatabase")!)
.SaveTrainParameters()
)
);
builder.Services.AddScoped<IUserRepository, UserRepository>();
builder.Services.AddScoped<IEmailService, EmailService>();
var app = builder.Build();
app.Run();Use ServiceTrain
Switch from Train to ServiceTrain to get metadata tracking:
public interface ICreateUserTrain : IServiceTrain<CreateUserRequest, User>;
public class CreateUserTrain : ServiceTrain<CreateUserRequest, User>, ICreateUserTrain
{
protected override async Task<Either<Exception, User>> RunInternal(CreateUserRequest input)
=> Activate(input)
.Chain<ValidateEmailJunction>()
.Chain<CreateUserInDatabaseJunction>()
.Chain<SendWelcomeEmailJunction>()
.Resolve();
}The RunInternal code is identical to Core — ServiceTrain adds the execution logging and DI around it.
Next: Effect docs for metadata, effect providers, and the ServiceTrain lifecycle.
Track 3: Full Stack
Add the mediator, scheduler, and dashboard for a complete platform.
dotnet new install Trax.Samples.Templates
dotnet new trax-scheduler -n MyAppThis scaffolds a project with:
- PostgreSQL persistence
TrainBusfor decoupled dispatch- Scheduler with cron-based manifests
- Dashboard at
/trax - A sample HelloWorld train
Or configure manually:
builder.Services.AddTrax(trax => trax
.AddEffects(effects => effects
.UsePostgres(connectionString)
.SaveTrainParameters()
.AddJunctionLogger(serializeJunctionData: true)
.AddJunctionProgress()
)
.AddMediator(typeof(Program).Assembly)
);
builder.Services.AddTraxDashboard();
var app = builder.Build();
app.UseTraxDashboard();
app.Run();Next:
- Mediator — decoupled dispatch with TrainBus
- Scheduling — cron jobs, retries, dead letters
- Dashboard — monitoring UI
- API — GraphQL interface
- Project Template — full template reference
- Samples & Deployment — the trains library pattern and deployment topologies
SDK Reference
> Activate | Chain | Resolve | Run / RunEither | AddTrax / AddEffects | UsePostgres | SaveTrainParameters | AddJunctionLogger | AddJunctionProgress | AddMediator | AddTraxDashboard | UseTraxDashboard