# Yak 01 — C# solution: the BEFORE situation (DB-backed domain classes) ## Context This exercise illustrates the transition from domain classes that inherit a DB base class (EF-style, or active-record-like) to plain domain objects + DTOs. See `before-after-dto.mmd` (and `before-after-dto-sketch.png`) for the diagram this yak implements in C#: - `DbContext` — the database context (EF fake) - `DbBase` — base class with an `Id`; depends on `DbContext` - `Client`, `Order` — domain classes **inheriting `DbBase`** - `WebApp` — consumes the domain classes directly Yak 02 will implement the "after" situation in the same solution. ## Tech constraints - .NET SDK: target **net8.0** (adjust if only another SDK is installed; note it in the commit message). - **Fake the EF magic — do NOT add real EF Core.** The point of the exercise is the *shape of the dependencies*, not EF's behavior. A fake `DbContext` keeps the project pure managed code: no native binaries, no SQLite, no provider quirks → guaranteed cross-platform (Windows/macOS/Linux). - Tests: **xUnit**, one test project. - Solution layout: ``` db-subclass-to-dto.sln src/ Before/ (net8.0 class library, namespace Before.*) After/ (net8.0 class library, namespace After.*) ← created in Yak 02 tests/ BeforeAfter.Tests/ (net8.0 xUnit project) ``` Yak 01 only creates the solution, the `Before/` project, and the test project (plus an empty `After/` project so the solution shape is final). ## "Magic" to fake on DbBase / DbContext Simulate EF's change tracker with a minimal fake: - `DbContext` holds a registration dictionary of entities it knows about. - `DbContext.Save()` iterates tracked `DbBase` entities: assigns a fresh `Guid` `Id` to any entity whose `Id` is `Guid.Empty`, and records it. - `DbBase` carries a back-reference to its owning `DbContext` (active-record-style "I know which context created me") — this is the dependency leak the exercise wants to expose. - `Client` has an `Orders` collection; `Order` has a `Client` back-reference. Adding an order to `client.Orders` sets `order.Client` (mimic EF navigation fix-up). - A `WebApp` type with methods that consume `Client`/`Order` directly, including one that demonstrates the leak: reaching the `DbContext` *through* a domain object (e.g. `client.DbContext`). Keep the fake small; this is an illustration, not an ORM. ## Required tests (BeforeTests) At minimum: 1. `Client` and `Order` derive from `DbBase` (`typeof(DbBase).IsAssignableFrom(typeof(Client))` etc.). 2. New `Client`/`Order` instances have `Id == Guid.Empty`. 3. `DbContext.Save()` assigns fresh, distinct `Guid` ids to saved entities (the faked EF magic). 4. Saved entities are registered with their `DbContext` (reachable via the back-reference). 5. Relation fix-up: `client.Orders.Add(order)` sets `order.Client == client`. 6. The leak: from a bare `Client`, you can reach the `DbContext` (`client.DbContext` is non-null after save) — assert this explicitly, comment that this is exactly what the "after" situation removes. 7. `WebApp` methods work on the domain classes directly. ## Acceptance criteria - `dotnet build db-subclass-to-dto.sln` succeeds with 0 warnings. - `dotnet test db-subclass-to-dto.sln` succeeds; all tests pass. - No NuGet packages beyond xUnit's default set (no EF Core, no SQLite, no AutoMapper). - Code + tests committed with a message referencing this yak. ## Open questions (answer before starting, defaults in parens) 1. Target framework net8.0 or something else? (net8.0) 2. Fake DbContext only, or do you also want a variant using real EF Core + `Microsoft.Data.Sqlite` (bundled native lib — still no install needed on Windows, but adds NuGet/ABI surface)? (fake only) 3. Any naming/style preference (file-scoped namespaces, records vs classes)? (file-scoped namespaces; plain classes)