Enterprise Patterns, Real Code: Implementing Fowler’s Ideas in C#
- Chris Woodruff
- November 28, 2025
- Patterns
- .NET, C#, dotnet, patterns, programming
- 0 Comments
How this series will work
In each article, I will:-
- Explain a pattern in plain language, with the original intent from Fowler’s catalog
-
- Show how it typically shows up in C# and .NET projects
-
- Give a focused example of when to use it and when to avoid it
-
- Connect it to neighboring patterns so you see design options, not isolated tricks
Pattern index
Use these links to jump to the pattern you care about right now.-
- Data Transfer Object (DTO)
Layered Architecture Pattern
Definition
Layered Architecture splits an application into distinct layers with clear responsibilities. Fowler’s baseline is:-
- Presentation: handles input and output
-
- Domain: holds business rules and domain logic
-
- Data source: manages persistence and integration with data stores
Where to use it
Layered Architecture fits:-
- ASP.NET Core applications that will grow beyond a few controllers
-
- Systems where different teams own UI, business rules, and infrastructure
-
- Codebases that must survive several technology shifts over their lifetime
Transaction Script Pattern
Definition
Transaction Script organizes business logic as procedures that handle a single request or use case end to end. Each script:-
- Reads input
-
- Performs calculations and decisions
-
- Persists changes
Where to use it
Transaction Script works best when:-
- The domain logic is simple and shallow
-
- You are building reports, admin utilities, or migration tools
-
- You need results quickly and long term complexity is limited
Domain Model Pattern
Definition
Domain Model concentrates business rules inside a rich object model. Entities and value objects express invariants and behavior. Instead of treating data as passive structures, you treat the domain as the center of gravity. Controllers and repositories orbit around it rather than injecting rules into every edge of the system.Where to use it
Domain Model earns its weight when:-
- The business rules are complex and interdependent
-
- Invariants matter more than raw throughput
-
- You expect requirements to evolve frequently
Service Layer Pattern
Definition
Service Layer defines a set of application operations that sit between the outside world and the domain model. It:-
- Coordinates multiple domain objects
-
- Handles transactions and security policies
-
- Exposes a clear API for controllers, message handlers, or other clients
Where to use it
Service Layer fits when:-
- You have multiple clients hitting the same core logic: web, background jobs, workers
-
- You want to expose a stable application API while the UI evolves
-
- Cross cutting concerns such as logging, permissions, and transaction boundaries must stay consistent
Active Record Pattern
Definition
Active Record merges domain objects with persistence. Each entity:-
- Maps directly to a database row
-
- Contains business logic
-
- Knows how to load and save itself
Where to use it
Active Record suits:-
- Small systems with straightforward tables
-
- Prototypes where getting something working matters more than deep abstraction
-
- Places where simple CRUD with light behavior is enough
Data Mapper Pattern
Definition
Data Mapper sits between domain objects and the database. It:-
- Loads domain objects from data stores
-
- Persists changes back
-
- Shields the domain from knowledge of how persistence works
Where to use it
Data Mapper pays off when:-
- You have a rich Domain Model
-
- The database schema must evolve independently of the object model
-
- You want to test domain logic without a database in the way
Repository Pattern
Definition
Repository represents a collection-like interface for accessing aggregates. It:-
- Hides queries and persistence details
-
- Exposes methods that work in domain terms, such as GetById, FindActiveForCustomer, Add, Remove
-
- Lets the domain talk in its own language instead of in SQL or query APIs
Where to use it
Repository helps when:-
- The same aggregate appears across many use cases
-
- You want consistent access patterns for aggregates
-
- You expect to support multiple query strategies or stores behind the same domain interface
Unit of Work Pattern
Definition
Unit of Work tracks changes to domain objects during a business transaction and writes them out as a single logical batch. It:-
- Records inserts, updates, and deletes
-
- Coordinates commit or rollback
-
- Provides a boundary for transactional behavior
Where to use it
Unit of Work is valuable when:-
- A single operation touches multiple aggregates or tables
-
- You need clear transactional boundaries for consistency
-
- You want to keep domain logic free of save calls
Identity Map Pattern
Definition
Identity Map ensures that each logical entity from the database exists only once in memory per scope. It:-
- Tracks loaded objects by identity
-
- Returns existing instances instead of creating new ones for the same key
-
- Helps avoid inconsistent in memory states for the same row
Where to use it
Identity Map matters when:-
- The same entity is loaded through different paths in one request
-
- You attach domain behavior to entities and depend on reference equality
-
- You care about performance costs of repeated materialization
Lazy Load Pattern
Definition
Lazy Load defers loading of related data until it is actually needed. Instead of fetching entire object graphs, you:-
- Load a root entity
-
- Represent associations as placeholders
-
- Trigger actual loading when code accesses the association
Where to use it
Lazy Load helps when:-
- Most use cases do not need full graphs
-
- Some navigations are expensive or remote
-
- You have to control query explosions carefully
Front Controller Pattern
Definition
Front Controller centralizes request handling for a web application. Instead of letting every page or endpoint own its own entry point, you:-
- Route all requests through a single handler
-
- Apply cross cutting logic in one place
-
- Delegate to controllers or handlers for detailed work
Where to use it
Front Controller aligns with:-
- Web applications that need consistent logging, authentication, and error handling
-
- Systems that must make routing decisions based on shared policies
-
- Architectures that use pipelines and middleware
Model View Controller (MVC) Pattern
Definition
Model View Controller splits UI logic into three parts:-
- Model: the underlying data and behavior
-
- View: rendering logic
-
- Controller: input handling and coordination
Where to use it
MVC suits:-
- Applications with complex UI interactions that depend on domain rules
-
- Teams that want clear separation between presentation logic and domain logic
-
- Systems that must support multiple views on the same model
Data Transfer Object (DTO) Pattern
Definition
Data Transfer Object carries data across process boundaries. It:-
- Aggregates fields into a serializable shape
-
- Avoids sending full domain objects across the wire
-
- Provides a contract between services, clients, or layers
Where to use it
DTOs are worth the effort when:-
- You are exposing public APIs
-
- Multiple clients consume your service, each with their own evolution pace
-
- You want to keep domain classes internal to your application
What comes next
The rest of this series will go pattern by pattern:-
- Each pattern gets its own post
-
- Each post includes C# examples, tests where relevant, and context from real projects
-
- The focus stays on tradeoffs, not worship of diagrams

