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 communicationCircuit Breaker, Outbox, Pipeline, Provider.
  • Persistence and domainRepository, Unit of Work, Specification.
  • Distributed architectureCQRS, Event Sourcing, Saga.
  • CompositionDependency Injection as a common language.

Each with its C# example, its idiomatic variants, and, especially, when you don't need it yet.

  • 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.