Mert Özen Further With Every Line

Blog

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

Series
64 posts found #yazilim-mimarisi
Event-Sourced Aggregates with the Decider Pattern: decide, evolve, and Given-When-Then Tests
Software Architecture PART 05

Event-Sourced Aggregates with the Decider Pattern: decide, evolve, and Given-When-Then Tests

The decider pattern splits an event-sourced model's decision logic into two pure functions: Decide produces new events from a command and a state, Evolve produces a new state from a state and an event. A decider for the stock ledger with C# 14 switch expressions, moving time into the command with TimeProvider, database-free Given-When-Then tests and a comparison with the OOP aggregate style, with real test output.

7 Nov 2026 14 min 4
What Is Event Sourcing? Storing What Happened Instead of State
Software Architecture PART 04

What Is Event Sourcing? Storing What Happened Instead of State

Event Sourcing stores what happened in an append-only event stream instead of the latest state, and derives state by folding those events. Using Bookstore's stock ledger: rehydration, audit, temporal queries, optimistic concurrency with an expected version, why an event store is not a message broker, why it goes together with CQRS, and its real costs.

7 Nov 2026 14 min 5
A Separate Read Model: Materialized Views, Synchronization, and Living with Eventual Consistency
Software Architecture PART 03

A Separate Read Model: Materialized Views, Synchronization, and Living with Eventual Consistency

A separate read model stores the screen's row precomputed from domain events; updated in the same transaction it stays immediately consistent, updated asynchronously in a separate database you have to live with eventual consistency. Inline projections, PostgreSQL materialized views, an asynchronous projector with a checkpoint, waiting on a position for read-your-own-writes, idempotent updates and a full rebuild, with real output.

7 Nov 2026 14 min 4
CQRS in a Single Database: Aggregates on the Write Side, Projections on the Read Side
Software Architecture PART 02

CQRS in a Single Database: Aggregates on the Write Side, Projections on the Read Side

CQRS in a single database means saving the aggregate through EF Core's change tracker on the write side and projecting from the same tables on the read side without ever touching the aggregate. What PlaceOrder and CancelOrder should return, a separate flat read DbContext, Dapper over a SQL view, and having PostgreSQL enforce that queries don't change state with read-only transactions, with real SQL and the 25006 error.

7 Nov 2026 14 min 4
What Is CQRS? From CQS to Command Query Responsibility Segregation
Software Architecture PART 01

What Is CQRS? From CQS to Command Query Responsibility Segregation

CQRS splits one model into two, one for writing (commands) and one for reading (queries); Greg Young took Meyer's method-level CQS principle up to the model level. We show with a real compiler error and a load count why an aggregate does not fit a list screen, then cover the three levels of CQRS, how it differs from Event Sourcing and MediatR, and Fowler's 'only where it pays off' warning.

7 Nov 2026 12 min 5
The Evolution of DDD and Common Mistakes: From the Blue Book to Dynamic Consistency Boundaries
Software Architecture PART 14

The Evolution of DDD and Common Mistakes: From the Blue Book to Dynamic Consistency Boundaries

DDD's most common mistake is skipping the strategic design left at the end of the Blue Book and taking only tactical words like entity, repository, and base class. A history from Evans's 2003 book to the DDD Reference, Vernon's aggregate rules, EventStorming, Team Topologies and Khononov, and the Dynamic Consistency Boundary that questions the aggregate; with an in-memory DCB example and a reading route after the series.

7 Nov 2026 13 min 5
End to End: Refactoring Bookstore's Ordering Context from Anemic CRUD to a Rich Model
Software Architecture PART 13

End to End: Refactoring Bookstore's Ordering Context from Anemic CRUD to a Rich Model

The safe way to move anemic CRUD code to a rich model is to pin current behavior with characterization tests first, then take the language, value object, aggregate boundary, invariant, and domain event steps as separate commits that each stay green. We transform Bookstore's Ordering in 11 commits and show refactoring toward deeper insight with a buy-3-pay-for-2 campaign, plus before/after metrics, all with real output.

7 Nov 2026 19 min 7
Domain Events: Raise, Collect, and Dispatch on SaveChanges
Software Architecture PART 12

Domain Events: Raise, Collect, and Dispatch on SaveChanges

An aggregate records what happened as a past-tense, immutable domain event in its own list; EF Core 10's SaveChangesInterceptor collects the events during SaveChanges, runs same-transaction handlers before the commit and side effects that leave the database after it. A mediator-free dispatcher, the nested SaveChanges and explicit transaction traps with real output, and how integration events and the outbox differ.

7 Nov 2026 16 min 7
Domain Services, Application Services, and the Anemic Domain Model
Software Architecture PART 11

Domain Services, Application Services, and the Anemic Domain Model

Behavior goes first to the entity or value object that owns it; a stateless domain calculation that naturally belongs to none of them becomes a domain service, while loading, saving, and the transaction stay in a thin application service. We move Bookstore's copied shipping rule out of anemic services into Order and a ShippingFeeCalculator, with real output, and cover policies, factories, and the trap of injecting repositories into domain services.

7 Nov 2026 17 min 6
Aggregate Design: Consistency Boundaries, Small Aggregates, and Referencing by Id
Software Architecture PART 09

Aggregate Design: Consistency Boundaries, Small Aggregates, and Referencing by Id

An aggregate is a consistency boundary that keeps true invariants consistent within a single transaction; the outside references only the root, and other aggregates are referenced only by id. We apply Vernon's four rules to Bookstore's Order and StockItem aggregates and work through a real EF Core run where a navigation property silently changes the catalog price, eventual consistency for stock, the 'whose job is it?' question and the Aggregate Design Canvas.

7 Nov 2026 10 min 4
The Always-Valid Domain Model: Protecting Invariants with Constructors, Factories, and Guards
Software Architecture PART 08

The Always-Valid Domain Model: Protecting Invariants with Constructors, Factories, and Guards

An always-valid domain model doesn't check invariants before saving, it makes violating them impossible: a private constructor, a static factory and guard clauses close every path to an invalid state. With Bookstore's Order we work through the at-least-one-item, 10-copies-per-book, single-currency and one-coupon rules, the limits of required/init and C# 14's field, the domain exception vs Result split, and the difference between input validation and invariants, with real output.

7 Nov 2026 12 min 6
Entities and Value Objects: Identity, Equality, and Immutable Models with C# Records
Software Architecture PART 07

Entities and Value Objects: Identity, Equality, and Immutable Models with C# Records

An entity is defined by an identity that lasts through time, a value object only by its value: two Money values are the same if amount and currency match, two Orders only if their Ids do. We write Money, Isbn and strongly typed ids with C# records and readonly record structs, map them with the complex types EF Core 10 recommends over owned types, and show the collection-in-record, struct default and with pitfalls with real output.

7 Nov 2026 14 min 8
Blog Map