Solution Patterns
Tactical recipes beyond the GoF. Pipeline, Provider, CQRS, Repository, Saga, Specification…
Patterns that are not in the original Gang of Four book but appear repeatedly in modern systems: processing pipelines, interchangeable providers, separation of read and write concerns, distributed transactions, network resiliency, and more.
#The Problem
There are problems that are not classic OO design and appear in any project of a certain size: how do I coordinate a transaction that spans three services? How do I avoid bringing down a provider that is already offline? How do I separate massive reads from critical writes? Without known recipes, each team reinvents the wheel — and usually invents it badly, discovering edge cases only in production.
#The Solution
These tactical patterns are battle-tested tools from the community:
Circuit Breaker for resiliency, Outbox for eventual consistency,
Repository and Specification for isolating persistence, CQRS and Saga for
separating responsibilities at scale. You name them once, and the whole team understands
what guarantees they provide and what problems they don't solve.
Some come from Domain-Driven Design (Repository, Specification, Unit of Work), others arise from distributed architecture (CQRS, Event Sourcing, Saga, Outbox), and others are simply plumbing mechanisms that every team ends up inventing (Pipeline, Provider, Circuit Breaker).
#Why we separated them from the GoF
Because their scale is different. While a Strategy lives within a class, a Saga coordinates multiple services, and an Outbox even affects how you configure your database. Mixing them with the 23 classics only causes confusion.
#In this chapter
- Resilience and communication —
Circuit Breaker,Outbox,Pipeline,Provider. - Persistence and domain —
Repository,Unit of Work,Specification. - Distributed architecture —
CQRS,Event Sourcing,Saga. - Composition —
Dependency Injectionas a common language.
Each with its C# example, its idiomatic variants, and, especially, when you don't need it yet.
#Related Readings
- If you're coming from the classics: Design Patterns.
- If you're deciding on the macro-structure: Application Architecture.
- Pipeline — Processes data through an ordered sequence of steps (stages) that transform its input into output.
- Producer / Consumer — Decouples work generation from work processing using an in-memory queue as an intermediate buffer.
- Provider Pattern (single) — Abstracts access to an external resource or service that is interchangeable and configurable at runtime.
- Specification — Encapsulates boolean-returning business rules into composable objects (AND, OR, NOT).
- Unit of Work — Maintains a list of operations affected by a business transaction and coordinates their writing.
- Repository — An intermediary between the domain and storage, exposing illusory in-memory collections.
- Dependency Injection — Provides an object with its dependencies from external sources instead of having it build them itself.
- CQRS — Separates the read model from the write model to optimize each independently.
- Event Sourcing — Persists state as an immutable sequence of events rather than the current state.
- Saga — Coordinates long-running transactions across services using steps and compensations.
- Transactional Outbox — Reliably publish events to a message broker from a transactional database.
- Circuit Breaker — Protects the system from cascading failures by cutting off calls to a struggling service.