# Yak 02 — C# solution: the AFTER situation (plain domain + DTOs + mappers) ## Context Depends on Yak 01 (solution, `Before/` project, test project already exist). Implement the "after" half of the exercise in the existing `After/` project and add tests. See `after-dto.mmd` for the diagram: - `Client`, `Order` — **plain** domain objects, no `DbBase` inheritance, no knowledge of `DbContext` - `ClientDto`, `OrderDto` — DTOs carrying the same data **including the relations** (`ClientDto.Orders`, back-references) - `Mappers` — hand-written mapping, each way: `ToClientDto`, `FromClientDto`, `ToOrderDto`, `FromOrderDto` - `DbContext`/`DbBase` — still exist (persistence layer), but the domain no longer subclasses/leaks them - `WebApp` — consumes **only DTOs** ## Rules - Do NOT modify `Before/` (it's the frozen "before" state). - Hand-write the mappers (no AutoMapper) — the mapping code is part of the illustration. Mappers must not mutate their inputs. - Keep the fake `DbContext`/`DbBase` for persistence in `After/` (or reuse the idea from `Before/`), but the domain types must not derive from `DbBase`. Persisting a domain object now requires explicit registration (e.g. a `DbContext.Save(client)` that copies into a tracked entity, or registers an adapter) — the direction of dependency is flipped. ## Required tests (AfterTests) At minimum, mirroring the Before tests where meaningful: 1. `Client`/`Order` do **not** derive from `DbBase`, and (via reflection) expose no `DbContext`-typed property or field — the leak is gone. 2. Mappers map all scalar fields, in both directions (`Client → ClientDto`, `ClientDto → Client`, same for `Order`). 3. Mappers map the relations: `Client.Orders` → `ClientDto.Orders`, and the `Order.Client` / `OrderDto.ClientDto` back-references stay consistent. 4. Round-trip: `FromX(ToX(domain))` equals the original domain state (compare by values, not reference); same for DTO round-trip. 5. Mappers do not mutate their input (snapshot fields, map, compare). 6. `WebApp` (after version) methods consume only `ClientDto`/`OrderDto`; assert the `After.WebApp` type references no domain or DbContext type in its public API (reflection over member signatures). 7. Persistence still works through the fake `DbContext` in the after world. ## Acceptance criteria - `dotnet build` and `dotnet test` succeed on the full solution (Before + After + tests), 0 warnings. - No NuGet packages beyond xUnit's default set. - `Before/` project unmodified (diff check). - Committed with a message referencing this yak. ## Open questions (answer before starting, defaults in parens) 1. How should the after-world persistence flip look — explicit `ctx.Save(domainObject)` with internal entity/DTO translation, or something else? (explicit Save with translation, minimal) 2. Are DTOs records (value equality helps round-trip tests) or plain classes? (records)