From ecdfd07dcb2a8ed848cb4c74e8a80b3ccf2646b5 Mon Sep 17 00:00:00 2001 From: Nano Taboada <87288+nanotaboada@users.noreply.github.com> Date: Sun, 15 Mar 2026 22:01:45 -0300 Subject: [PATCH 1/3] docs(readme): update architecture diagram and add explanatory text MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fixes inverted Data→Models arrow (now Models→Data) - Moves Swashbuckle to Layer 1 alongside Program and Serilog - Adds ASP.NET Core (Layer 2) and EF Core (Layer 4) as explicit nodes - Removes Configurations node (plumbing, not a meaningful concern) - Reorders subgraph declarations from 4→1 to 1→4 - Adds Arrow Semantics, Composition Root, Layered Architecture, and Color Coding explanatory sections Co-Authored-By: Claude Sonnet 4.6 --- .github/copilot-instructions.md | 1 + README.md | 98 +++++++++++++++++++++------------ 2 files changed, 63 insertions(+), 36 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index a35a7aa..4dac0fa 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -118,4 +118,5 @@ Example: `feat(api): add player search endpoint (#123)` feat(scope): description (#issue) Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> +Co-authored-by: Claude ``` diff --git a/README.md b/README.md index 060fa3e..3595085 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ Proof of Concept for a RESTful API built with .NET 10 (LTS) and ASP.NET Core. Ma ## Tech Stack | Category | Technology | -|----------|------------| +| -------- | ---------- | | **Framework** | [.NET 10](https://github.com/dotnet/core) (LTS) | | **Web Framework** | [ASP.NET Core 10.0](https://github.com/dotnet/aspnetcore) | | **API Documentation** | [Swashbuckle](https://github.com/domaindrivendev/Swashbuckle.AspNetCore) (OpenAPI 3.0) | @@ -95,7 +95,7 @@ test/Dotnet.Samples.AspNetCore.WebApi.Tests/ ## Architecture -Dependencies flow from data layer through repositories and services to controllers. External dependencies (AutoMapper, FluentValidation, Serilog, Swashbuckle) integrate at their respective layers. +Layered architecture with dependency injection via constructors and interface-based contracts. ```mermaid @@ -112,11 +112,19 @@ Dependencies flow from data layer through repositories and services to controlle graph RL - Models[Models] + Tests[Tests] - subgraph Layer4[" "] - Data[Data] - Repositories[Repositories] + subgraph Layer1[" "] + Program[Program] + Serilog[Serilog] + Swashbuckle[Swashbuckle] + end + + subgraph Layer2[" "] + Controllers[Controllers] + Validators[Validators] + FluentValidation[FluentValidation] + AspNetCore[ASP.NET Core] end subgraph Layer3[" "] @@ -126,44 +134,42 @@ graph RL MemoryCache[MemoryCache] end - subgraph Layer2[" "] - Controllers[Controllers] - Validators[Validators] - FluentValidation[FluentValidation] - Swashbuckle[Swashbuckle] + subgraph Layer4[" "] + Repositories[Repositories] + Data[Data] + EFCore[EF Core] end - subgraph Layer1[" "] - Program[Program] - Configurations[Configurations] - Serilog[Serilog] - end + Models[Models] - Tests[Tests] + %% Strong dependencies - %% Application flow - Data --> Models - Models --> Repositories - Repositories --> Services - Services --> Controllers + %% Layer 1 Controllers --> Program + Serilog --> Program + Swashbuckle --> Program - %% Layer connections - Models --> Mappings + %% Layer 2 + Services --> Controllers Validators --> Controllers - Mappings --> Services - - %% External Dependencies connections - AutoMapper --> Mappings FluentValidation --> Validators - Serilog --> Program - Swashbuckle --> Controllers + AspNetCore --> Controllers - %% Supporting Features connections - Configurations --> Program + %% Layer 3 + Repositories --> Services MemoryCache --> Services + Mappings --> Services + AutoMapper --> Mappings + Models --> Mappings + + %% Layer 4 + Models --> Repositories + Models --> Data + EFCore --> Data + EFCore -.-> Repositories + + %% Soft dependencies - %% Tests connections Services -.-> Tests Controllers -.-> Tests @@ -176,10 +182,30 @@ graph RL class Data,Models,Repositories,Services,Controllers,Program,Validators,Mappings core; class AutoMapper,FluentValidation,Serilog,Swashbuckle deps; class Tests test; - class Configurations,MemoryCache feat; + class AspNetCore,EFCore,MemoryCache feat; ``` -*Layered architecture: Core application flow (blue), supporting features (yellow), external dependencies (red), and test coverage (green). Not all dependencies are shown.* +### Arrow Semantics + +Arrows point from a dependency toward its consumer. Solid arrows (`-->`) denote **strong (functional) dependencies**: the consumer actively invokes behavior — registering types with the IoC container, executing queries, applying mappings, or handling HTTP requests. Dotted arrows (`-.->`) denote **soft (structural) dependencies**: the consumer only references types or interfaces without invoking runtime behavior. This distinction follows UML's `«use»` dependency notation and classical coupling theory (Myers, 1978): strong arrows approximate *control or stamp coupling*, while soft arrows approximate *data coupling*, where only shared data structures cross the boundary. + +### Composition Root Pattern + +The `Program` module acts as the composition root — it is the sole site where dependencies are registered with the IoC container, wired via interfaces, and resolved at runtime by the ASP.NET Core host. Rather than explicit object construction, .NET relies on built-in dependency injection: `Program` registers services, repositories, DbContext, mappers, validators, and middleware, and the framework instantiates them on demand. This pattern enables dependency injection, improves testability, and ensures no other module bears responsibility for type registration or lifecycle management. + +### Layered Architecture + +The codebase is organized into four conceptual layers: Initialization (`Program`), HTTP (`Controllers`, `Validators`), Business (`Services`, `Mappings`), and Data (`Repositories`, `Data`). + +Framework packages and third-party dependencies are co-resident within the layer that consumes them: `Serilog` and `Swashbuckle` inside Initialization, `ASP.NET Core` and `FluentValidation` inside HTTP, `AutoMapper` inside Business, and `EF Core` inside Data. `ASP.NET Core`, `EF Core`, and `MemoryCache` are Microsoft platform packages (yellow); `AutoMapper`, `FluentValidation`, `Serilog`, and `Swashbuckle` are third-party packages (red). + +The `Models` package is a **cross-cutting type concern** — it defines shared entities and DTOs consumed across multiple layers via strong dependencies, without containing logic or behavior of its own. Strong dependencies flow strictly downward through the layers, preserving the layer rule: no layer reaches upward to invoke behavior in a layer above it. + +### Color Coding + +Core packages (blue) implement the application logic, supporting features (yellow) are Microsoft platform packages, third-party dependencies (red) are community packages, and tests (green) ensure code quality. + +*Simplified, conceptual view — not all components or dependencies are shown.* ## API Reference @@ -387,7 +413,7 @@ STORAGE_PATH=/storage/players-sqlite3.db ## Command Summary | Command | Description | -|---------|-------------| +| ------- | ----------- | | `dotnet watch run --project src/...` | Start development server with hot reload | | `dotnet build` | Build the solution | | `dotnet test` | Run all tests | From c559aba755d7319973cb5c010d3953e68a912339 Mon Sep 17 00:00:00 2001 From: Nano Taboada <87288+nanotaboada@users.noreply.github.com> Date: Sun, 15 Mar 2026 22:22:45 -0300 Subject: [PATCH 2/3] docs(readme): clarify dependency direction in Layered Architecture section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rewords "flow strictly downward" to emphasize consumer→dependency direction, making the layer rule unambiguous Co-Authored-By: Claude Sonnet 4.6 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3595085..9ca72fb 100644 --- a/README.md +++ b/README.md @@ -199,7 +199,7 @@ The codebase is organized into four conceptual layers: Initialization (`Program` Framework packages and third-party dependencies are co-resident within the layer that consumes them: `Serilog` and `Swashbuckle` inside Initialization, `ASP.NET Core` and `FluentValidation` inside HTTP, `AutoMapper` inside Business, and `EF Core` inside Data. `ASP.NET Core`, `EF Core`, and `MemoryCache` are Microsoft platform packages (yellow); `AutoMapper`, `FluentValidation`, `Serilog`, and `Swashbuckle` are third-party packages (red). -The `Models` package is a **cross-cutting type concern** — it defines shared entities and DTOs consumed across multiple layers via strong dependencies, without containing logic or behavior of its own. Strong dependencies flow strictly downward through the layers, preserving the layer rule: no layer reaches upward to invoke behavior in a layer above it. +The `Models` package is a **cross-cutting type concern** — it defines shared entities and DTOs consumed across multiple layers via strong dependencies, without containing logic or behavior of its own. Dependencies always flow from consumers toward their lower-level types: each layer depends on (consumes) the layers below it, and no layer invokes behavior in a layer above it. ### Color Coding From 3f4fbd44368af2bc3588677202af7a0106a913f9 Mon Sep 17 00:00:00 2001 From: Nano Taboada <87288+nanotaboada@users.noreply.github.com> Date: Sun, 15 Mar 2026 22:28:33 -0300 Subject: [PATCH 3/3] =?UTF-8?q?docs(readme):=20add=20missing=20Data?= =?UTF-8?q?=E2=86=92Repositories=20dependency=20in=20diagram?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Repositories consume DbContext (Data) at runtime via constructor injection; the edge was missing from the Layer 4 arrows Co-Authored-By: Claude Sonnet 4.6 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9ca72fb..ae5c85e 100644 --- a/README.md +++ b/README.md @@ -165,6 +165,7 @@ graph RL %% Layer 4 Models --> Repositories Models --> Data + Data --> Repositories EFCore --> Data EFCore -.-> Repositories