2.9 KiB
2.9 KiB
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, noDbBaseinheritance, no knowledge ofDbContextClientDto,OrderDto— DTOs carrying the same data including the relations (ClientDto.Orders, back-references)Mappers— hand-written mapping, each way:ToClientDto,FromClientDto,ToOrderDto,FromOrderDtoDbContext/DbBase— still exist (persistence layer), but the domain no longer subclasses/leaks themWebApp— 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/DbBasefor persistence inAfter/(or reuse the idea fromBefore/), but the domain types must not derive fromDbBase. Persisting a domain object now requires explicit registration (e.g. aDbContext.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:
Client/Orderdo not derive fromDbBase, and (via reflection) expose noDbContext-typed property or field — the leak is gone.- Mappers map all scalar fields, in both directions
(
Client → ClientDto,ClientDto → Client, same forOrder). - Mappers map the relations:
Client.Orders→ClientDto.Orders, and theOrder.Client/OrderDto.ClientDtoback-references stay consistent. - Round-trip:
FromX(ToX(domain))equals the original domain state (compare by values, not reference); same for DTO round-trip. - Mappers do not mutate their input (snapshot fields, map, compare).
WebApp(after version) methods consume onlyClientDto/OrderDto; assert theAfter.WebApptype references no domain or DbContext type in its public API (reflection over member signatures).- Persistence still works through the fake
DbContextin the after world.
Acceptance criteria
dotnet buildanddotnet testsucceed 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)
- 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) - Are DTOs records (value equality helps round-trip tests) or plain classes? (records)