Mert Özen Further With Every Line

Blog

Mert Özen's blog posts on software development, backend, frontend, and DevOps.

Series
8 posts found
Inverting Dependencies: Where Layered Architecture Gets Stuck
Software Architecture PART 01

Inverting Dependencies: Where Layered Architecture Gets Stuck

In a layered architecture compile-time dependencies flow downward, so business rules get locked to EF Core, SQLite and external APIs; the fix is to keep the runtime call direction but move the interfaces into the domain project that uses them, turning the reference arrow inward. Shown with Bookstore's "test without a database" and "switch carriers" scenarios, the "I added an interface, done" fallacy, and the idea shared by Hexagonal, Onion and Clean.

7 Nov 2026 12 min 5
Hexagonal Architecture (Ports & Adapters): Isolating the Application from the Outside World
Software Architecture PART 02

Hexagonal Architecture (Ports & Adapters): Isolating the Application from the Outside World

Hexagonal Architecture (Cockburn, 2005) keeps the application equally distant from UI, tests, batch scripts and the database: the outside world talks through purpose-based ports, and each technology plugs in through an adapter. In Bookstore we drive the IPlaceOrder driving port from a Minimal API, a console CSV import and an xUnit test, and back the IOrderStore driven port with EF Core and in-memory adapters; plus ASP.NET Core's IServer and common misreadings of the hexagon.

7 Nov 2026 12 min 7
Onion Architecture: Domain Model at the Center, Infrastructure on the Outer Ring
Software Architecture PART 03

Onion Architecture: Domain Model at the Center, Infrastructure on the Outer Ring

Onion Architecture (Palermo, 2008) builds the application around an independent domain model: inner rings define interfaces, outer rings implement them, all coupling points toward the center, and the core can be compiled and run without infrastructure. We place Bookstore's ordering code into Domain Model, Domain Services and Application Services rings and show how it differs from layered and Hexagonal, how rings relate to projects, and the ASP.NET Core Identity example.

7 Nov 2026 12 min 5
Clean Architecture: The Dependency Rule, Use Cases, and Data Crossing Boundaries
Software Architecture PART 04

Clean Architecture: The Dependency Rule, Use Cases, and Data Crossing Boundaries

Clean Architecture (Martin, 2012) has one rule, the Dependency Rule: source code dependencies point only inward, and what crosses a boundary is a simple data structure shaped for the inner circle, not an entity or a database row. In Bookstore: the four circles, the JSON cycle error caused by returning an EF Core row, the output port and presenter versus the pragmatic ASP.NET Core counterpart of a handler returning a Result, and a comparison of Hexagonal, Onion and Clean.

7 Nov 2026 12 min 8
The Application Layer and Use Cases: Handlers, Validation, and Transaction Boundaries Without MediatR
Software Architecture PART 06

The Application Layer and Use Cases: Handlers, Validation, and Transaction Boundaries Without MediatR

In the Application layer each use case is a single-purpose handler class: input validation stays in Web, business rules stay in the Domain, expected failures come back as a Result, and a single SaveChanges draws the transaction boundary. Adding cross-cutting concerns with Scrutor decorators instead of MediatR, and MediatR's licensing after 13.0.0.

7 Nov 2026 16 min 9
Persistence Ignorance and Infrastructure Adapters: EF Core, HttpClient, and External Services
Software Architecture PART 07

Persistence Ignorance and Infrastructure Adapters: EF Core, HttpClient, and External Services

Persistence ignorance means domain classes don't know which database or ORM they are written to; with EF Core you keep the mapping in Infrastructure through IEntityTypeConfiguration, but rules such as constructor binding and getter-only properties still shape the domain. Wrapping the shipping company's API in a driven adapter with a typed HttpClient, keeping the external model out, and the generic repository and IQueryable trap.

7 Nov 2026 14 min 5
Testing and Protecting Clean Architecture: Core Tests, Adapter Tests, and Architecture Tests
Software Architecture PART 08

Testing and Protecting Clean Architecture: Core Tests, Adapter Tests, and Architecture Tests

In Clean Architecture you test the core without a database using in-memory adapters, test the adapters against the production SQL Server with Testcontainers, and make the Dependency Rule unbreakable in CI with ArchUnitNET rules. The decimal precision problem SQLite hid, violations the compiler misses, the trap of a rule that selects nothing without Types(true), and a note that NetArchTest hasn't been updated since 2021.

7 Nov 2026 16 min 8
When Is Clean Architecture Too Much? Template Cargo Cults, Interface Explosion, and a Pragmatic Path
Software Architecture PART 09

When Is Clean Architecture Too Much? Template Cargo Cults, Interface Explosion, and a Pragmatic Path

Clean Architecture is too much for CRUD-heavy, short-lived or single-adapter small services with no business rules to protect, and pays off in long-lived regions with rules and several adapters. The symptoms of template cargo cults and interface explosion, protecting the same Dependency Rule with a single project and ArchUnitNET tests, and migrating a layered project gradually with FreezingArchRule.

7 Nov 2026 13 min 10
Blog Map