# Chain

Executes a junction, wiring its input from Memory and storing its output back into Memory. This is the primary method for composing junctions into a train pipeline. If any junction fails (returns `Left`), subsequent junctions are short-circuited.

Every `Chain` overload is a protected method on `Train<TInput, TReturn>` and returns a `MonadTask<TInput, TReturn>`, an awaitable wrapper around the chain that carries the same `Chain`, `IChain`, `ShortCircuit`, `Extract`, `AddServices` and `Resolve` methods, so calls continue fluently across async junctions. A chain always ends in `.Resolve()`.

## Chain\<TJunction\>()

Creates and executes a junction. Input is auto-extracted from Memory. The junction's `TIn`/`TOut` types are resolved via reflection from its `IJunction<TIn, TOut>` implementation.

```csharp
protected MonadTask<TInput, TReturn> Chain<TJunction>() where TJunction : class
```

| Type Parameter | Constraint | Description |
|---------------|------------|-------------|
| `TJunction` | `class` | The junction type. Must implement `IJunction<TIn, TOut>` for some `TIn`/`TOut`. |

This is the overload used in most trains:

```csharp
protected override Task<Either<Exception, OrderResult>> Junctions() =>
    Chain<ValidateOrder>()          // Creates ValidateOrder, extracts its input from Memory
        .Chain<ProcessPayment>()    // Creates ProcessPayment, extracts its input from Memory
        .Resolve();
```

## Chain\<TJunction\>(TJunction junctionInstance)

Executes a pre-created junction instance. Input is auto-extracted from Memory.

```csharp
protected MonadTask<TInput, TReturn> Chain<TJunction>(TJunction junctionInstance) where TJunction : class
```

| Parameter | Type | Description |
|-----------|------|-------------|
| `junctionInstance` | `TJunction` | A pre-created junction instance |

Useful when you need to configure a junction before executing it:

```csharp
protected override Task<Either<Exception, OrderResult>> Junctions() =>
    Chain(new ProcessPayment { Gateway = "stripe" }).Resolve();
```

## Chain\<TJunction, TIn, TOut\>() and Chain\<TJunction, TIn\>()

Explicit-typed overloads for a junction whose input and output types cannot be inferred from its interface, for example one that implements `IJunction<,>` more than once. The types are stated rather than discovered by reflection.

```csharp
protected MonadTask<TInput, TReturn> Chain<TJunction, TIn, TOut>(TJunction junction)
    where TJunction : IJunction<TIn, TOut>

protected MonadTask<TInput, TReturn> Chain<TJunction, TIn, TOut>()
    where TJunction : IJunction<TIn, TOut>, new()

// Unit output
protected MonadTask<TInput, TReturn> Chain<TJunction, TIn>(TJunction junction)
    where TJunction : IJunction<TIn, Unit>

protected MonadTask<TInput, TReturn> Chain<TJunction, TIn>()
    where TJunction : IJunction<TIn, Unit>, new()
```

| Type Parameter | Description |
|---------------|-------------|
| `TJunction` | The junction type |
| `TIn` | The input type taken from Memory |
| `TOut` | The output type stored in Memory (`Unit` for the two-parameter form) |

The parameterless forms construct the junction with `new()`, so they take no constructor dependencies. Pass an instance when the junction needs them.

---

## Behavior

1. If the train already has an exception, the junction is **skipped** (short-circuited). Nothing is built for it: the junction, its constructor dependencies and its input are not resolved from Memory or the container.
2. The junction's input is extracted from Memory by type.
3. The junction is executed via `RailwayJunction`.
4. On **success** (Right): the output is stored in Memory by its type. Tuple outputs are decomposed into individual Memory entries.
5. On **failure** (Left): the exception is captured and all subsequent Chain calls are short-circuited.

## Remarks

- `Chain<TJunction>()` creates the junction itself, through its single public constructor, whose parameters are resolved from Memory by type, DI services included. A junction Trax cannot build that way (more or fewer than one public constructor, an abstract class, or an interface) is refused when the chain is read, so the [startup check](/docs/core/trains-and-junctions#the-host-checks-every-chain-before-it-serves-traffic) keeps the host from starting; outside a host it fails the train with a `TrainException` naming the junction and its constructor count. A junction passed as an instance, `Chain(instance)`, is not checked, because its constructors never run.
- When a constructor argument or the junction's input is in neither Memory nor the container, the train fails with a `TrainException` naming the junction, the train and the missing type, for example `"Junction 'ClockJunction' (train 'ScheduleTrain') needs 'IClock' as a constructor argument, but nothing earlier in the chain produced one and it is not registered in the container. Register it or chain a junction that outputs it first."`. On a generic host the [startup check](/docs/core/trains-and-junctions#the-host-checks-every-chain-before-it-serves-traffic) finds a missing constructor argument before the first run and refuses to start; this run-time failure is what a host without the check (the Lambda runner, a bare `ServiceProvider`, `SkipChainVerification()`) sees.
- `TIn`/`TOut` are discovered via reflection from the junction's `IJunction<,>` interface at runtime.
- See [Memory](/docs/core/memory) for how type-based lookup works, including tuple handling.

## SynchronizationContext Safety

The chain is asynchronous end to end: each junction is awaited with `ConfigureAwait(false)`, and nothing blocks on a junction's task. That keeps chains safe in environments with a single-threaded `SynchronizationContext` such as Blazor Server, WPF, WinForms, and legacy ASP.NET.
