---
title: Configure a layout fluently
summary: Build an IFileConfiguration in code via FileConfiguration<T> and FileLayoutBuilder instead of attributes.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-09-15
library: SAIF.Framework.Common.Files
reference_type: package
operation_id: OP-04
trigger: Consumer subclasses FileConfiguration<T> and calls the protected builder methods in its constructor
---

# Configure a layout fluently

`FileConfiguration<T>` plus `FileLayoutBuilder` offer a code-first alternative to the attribute-based layout declared for [Read a typed flat file](read-typed-flat-file.md) and [Write a typed flat file](write-typed-flat-file.md), letting a consumer describe format and per-property layout with a fluent API instead of class/property attributes.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-04 |
| **Trigger** | A consumer subclasses `FileConfiguration<T>` and calls the protected builder methods in its constructor.* |
| **Inputs** | Lambda property expressions. |
| **Outputs** | An `IFileConfiguration` usable by the read (OP-01) and write (OP-03) operations. |
| **Primary components** | `FileConfiguration<T>`, `FileLayoutBuilder` |
| **Entry point** | `Common\SAIF.Common.Files\Core\Configurations\FileConfiguration.cs`, `Common\SAIF.Common.Files\Core\Configurations\FileLayoutBuilder.cs` |

## Steps

1. **Fix the format** — the constructor sets `Format`, marks `IsDefault = true`, and derives the delimiter for `Csv`/`TabDelimited`.
2. **Bind the record and index properties** — `Record(x => x.Value)` / `Index(x => x.Index)` resolve `PropertyInfo` via the delegated `SAIF.Framework.Common` extension `ExpressionExtensions.GetPropertyInfo` (traced source: `Common\SAIF.Common\Extensions\ExpressionExtensions.cs`).
3. **Declare a layout** — `Layout(x => x.PropertyName)` (constrained to `IConvertible`) or `CustomLayout()` appends a `FileRecordLayout` with a sequential `Id` and returns an `IFileLayoutBuilder`.
4. **Chain builder calls** to set element/fixed position, format string, title, id, trim, alignment/padding, read/write direction, and converter delegates.
   - `ReadCustom` forces the layout read-only; `WriteCustom` forces it write-only ([BR-016](../business-rules.md#br-016-readcustom-and-writecustom-force-layout-direction)).

## Process flow

```mermaid
flowchart TD
	Start(["Consumer subclasses<br>FileConfiguration<T>"]) --> Fix["Constructor fixes Format /<br>IsDefault / delimiter"]
	Fix --> Bind["Record(x => x.Value) /<br>Index(x => x.Index)<br>resolve PropertyInfo"]
	Bind --> Layout["Layout(x => x.PropertyName) /<br>CustomLayout()<br>appends FileRecordLayout"]
	Layout --> Chain["Chained builder calls set<br>position, format, title,<br>trim, alignment, converters, direction"]
	Chain --> EndOk(["IFileConfiguration ready<br>for OP-01 / OP-03"])
```

## Failure and edge-case behavior
- A layout marked `ReadCustom` is excluded from the writable-layout set, and one marked `WriteCustom` is excluded from the readable-layout set, so a caller that expects bidirectional mapping from a one-directional custom layout will silently see the property omitted on the opposite operation ([BR-016](../business-rules.md#br-016-readcustom-and-writecustom-force-layout-direction)).

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)

> **Note:** Statements marked with `*` were inferred from code structure, naming
> conventions, or contextual evidence where direct confirmation was not available
> in source artifacts.

## Sources
- Common\SAIF.Common.Files\Core\Configurations\FileConfiguration.cs
- Common\SAIF.Common.Files\Core\Configurations\FileLayoutBuilder.cs
- Common\SAIF.Common.Files\Core\Configurations\FileRecordLayout.cs
- Common\SAIF.Common\Extensions\ExpressionExtensions.cs
