Clean Architecture
Implementing in .NET
Ian Cooper
@ICooper
Who are you?
• Software Developer for more than 20 years
• Worked mainly for ISVs
• Reuters, SunGard, Misys, Huddle
• Worked for a couple of MIS departments
• DTI, Beazley
• Microsoft MVP for C#
• Interested in architecture and design
• Interested in Agile methodologies and practices
• No smart guys
• Just the guys in this room
2
3
Agenda
• On Modules
• On Layering
• On Domains
• On Clean Architecture
• On Implementing
4
Robert Martin
Ivar Jacobson
Alistair Cockburn Jeffrey Palermo
5
On Modules
5 6
Module
The façade hides
details. A coarse
grained façade
minimizes the surface
are depended upon by
a client. Coarse Grained Facade
A client cannot access Implementation Details
implementation
details – information
hiding principle
7
Modules
Coarse Grained Facade Coarse Grained Facade
We can slice up a Implementation Details Implementation Details
system into multiple
modules. A module’s details
should depend upon
This allows teams to another module’s
work independently. Coarse Grained Facade abstractions (façade).
It is easier to learn a Implementation Details
system, module by The abstraction
module. (façade) of a module,
should not depend on
It is easier to reason the details of another
about modules Coarse Grained Facade Coarse Grained Facade
module.
Implementation Details Implementation Details
8
Cohesion and
Coupling
Coarse Grained Facade Coarse Grained Facade
Because we depend Implementation Details Implementation Details
upon an abstraction,
we minimize the
A module is not a step
dependencies between
in the flow of the
code in modules.
system, instead it
Coarse Grained Facade hides design details.
We have low coupling
Implementation Details
Because we hide
details about a single
responsibility we have
high cohesion
Coarse Grained Facade Coarse Grained Facade
Implementation Details Implementation Details
9
High and Low
Coarse Grained Facade Coarse Grained Facade
A high level module
Implementation Details Implementation Details
has dependencies
Coarse Grained Facade
Implementation Details
Coarse Grained Facade Coarse Grained Facade
Implementation Details Implementation Details A low level module
has no dependencies
10
Interchangeability
Room Booking Module Room Booking Module
Implementation Details Implementation Details
If two modules present the same abstraction, in other words have the same contract with a client then we can swap one for another.
This allows us to change implementations, for modifiability or business requirements
Substitution
Coarse Grained Facade Coarse Grained Facade
Implementation Details Implementation Details
Because a module
We can isolate a Coarse Grained Facade implements an
module for testing by abstraction, we can
swapping its Implementation Details substitute it with a
dependencies for a dummy to defer a
stub design decision, whilst
working on other
modules
12
Modules in .NET
In .NET a module simply means a compiled file, which is linked into an
assembly, but we need a higher level concept for information hiding
Assembly – is .NET’s high level module concept
We can control what we export with access modifiers: public, internal
& private
This gives us information hiding
We can reuse by creating a reference from one assembly to another
13
On Layering
5 14
1: If I change the façade of A,
the implementation details of C Cyclic
which depend on it need to
change. Dependency
I need to build A, then build C.
2: Now if this caused the
C
interface of C to also change, it A Coarse Grained Facade Coarse Grained Facade
would force the
implementation details of B to Implementation Details Implementation Details
change.
I need to build A, then build C,
then build B.
Coarse Grained Facade
3: In turn, if this caused the
interface of B and thus Implementation Details
implementation of A to change
B
I need to build A, then build C,
then build B, then build A, then
B.
I have a cyclic dependency
15
Layers
A D UI
Domain
Relaxed Model
Only
B
C Infrastructure
16
Dependency
Inversion A D
Implements
Interface
UI
Creates D
Passes to B
Domain
Exposes
B Interface D Requirements
as Interface
C Infrastructure
17
On Domains
20 18
We can distinguish two types of ‘business logic’
Domain logic, having to do purely with the domain, such as calculating an
insurance premium, or figuring out the shortest path to ship a package.
Application logic, having to do with application responsibilities, often
referred to as workflow logic
19
UI
A
B Domain
Service
Entity
D
Infrastructure
20
There are two basic implementation variations
21
In the domain facade approach a Service Layer is implemented as a
set of thin facades over a Domain Model, exhibiting the defining
characteristics of Service Layer.
The classes implementing the facades don’t implement any
business logic. The Domain Model implements all of the business
logic.
The thin facades establish a boundary and set of operations through
which client layers interact with the application
22
In the operation script approach a Service Layer is implemented as a
set of thicker classes that directly implement application logic domain
object classes are mainly dumb objects holding state.
The operations available to clients of a Service Layer are
implemented as scripts, organized several to a class defining a
subject area of related logic.
Each such class forms an application “service,” and it’s common for
service type names to end with “Service.”
23
Ports and Adapters
A ports & adapters architectural style (Hexagonal Architecture) is a variation of the
layered architectural style which makes clear the separation between the:
application - which contains the rules of our application
adapters, which abstract the inputs to the application and our
outputs
ports, which are ‘purposeful conversations’ between the actor, via the
adapter, and the domain model
24
Application
Adapter
Port
25
Infrastructure
E Adapter UI
A
B <<interface>> D
Port Domain
Dependency
Inversion Application
C
26
Ivar Jacobson
27
28
Boundary-Controller-Entity
29
Boundary
The Boundary is an object that interfaces with system actors: user
interfaces, gateways, proxies etc.
30
Entity
Entities are objects representing system data: Customer, Transaction, Cart, etc.
31
Controller (Interactor)
Controllers are objects that mediate between boundaries and entities. They
orchestrate the execution of commands coming from the boundary.
32
33
Infrastructure
E Adapter UI
A
B <<interface>> D
Port Domain
Application
C
34
Controllers (Interactors) are objects that implement use cases. There
is an interactor for every use case. Name them after the use case. It
executes the use case by talking to entities and boundaries. All the
interactors together contain your application specific business logic
or rules.
A port is the 'use case boundary'. Use cases become problematic
when they become focused on technology concerns. Use cases written
against the ports can elide those concerns and focus on the
application rules, making them easier to write and maintain.
35
36
There is a correlation here between the use case boundary and the
test boundary - tests should focus on the behaviour expressed by a use
case, not on a unit of code.
37
38
39
40
On Clean Architecture
30 41
Depend
Inwards
Dependency
Inversion
Request Model
Entity
Interactor Entity
Delivery Entity
Boundary <<interface>> Entity
Mechanism
Use Cases
Response
Data Structure Model Entity Gateway
<<interface>>
Frameworks &
Drivers
Interface Adapters
44
Request Model
Entity
Interactor Entity
Entity
API Framework Web Controller <<interface>> Entity
Use Cases
Presenter Response
Response Entity Gateway
Data Structure <<interface>> Model
Model <<interface>>
Frameworks &
Drivers
Interface Adapters ViewModel
View <<interface>>
45
Request Model
Entity
Interactor Entity
API Entity
Web Controller <<interface>> Entity
Framework
Use Cases
Response
Data Structure Model Entity Gateway
<<interface>>
Frameworks &
Drivers
Delivery
Interface Adapters
Mechanism
DB
46
On Implementing
Port, Boundary, Interactor, call it what you will but how do we do it?
40 47
Command
Design Pattern
Command - Declares an interface for executing an
operation.
ConcreteCommand –Defines a binding between a
Receiver object and an action. Implements Execute
by invoking the corresponding operation(s) on
Receiver.
Client – creates a ConcreteCommand object and sets
its receiver.
Invoker - asks the command to carry out the request.
48
Request Model Command
Entity
ICommand Entity
Delivery Entity
Boundary <<interface>> Entity
Mechanism
Use Cases
Response
Data Structure Model Entity Gateway
<<interface>>
Frameworks &
Drivers
Interface Adapters
49
Command Dispatcher
Invoker - has a lit of Commands that are to be
executed
Command - represents the request to be processed,
encapsulating the parameters to be passed to the
command-handler to perform the request
Command Handler - specifies the interface that any
command handler must implement
Concrete Command Handler – implements the
request
Command Dispatcher – Allows dynamic registration
of Command Handlers and looks up handlers
for commands, by matching command and handler
key.
Client – registers Commands with the Command
Dispatcher.
50
Request Model AsyncRequest
Handler
Entity
IHandleRequests Entity
XUnit Entity
Test <<interface>> Entity
Framework
Use Cases
Response
Data Structure Model Entity Gateway
<<interface>>
Frameworks &
Drivers
Delivery
Interface Adapters
Mechanism
In-Memory
DB
51
Demo
52
53