Clean Architecture – Interface Adapters Example
Today I would like to look at a simple Clean Architecture example to see what part the Interface Adapters shell plays in data access.
I can’t wait until next time when we will increase the capability of our Interface Adapters layer by introducing data caching.
OK, let’s get into it.
Say we have a system that we have designed with Clean Architecture guidelines in mind.
There is some business logic, a use case class, that needs access to customer data, and it gets this via an ICustomerRepository
interface:
public interface ICustomerRepository { Customer GetCustomer(string emailAddress); }
Note: For the sake of simplicity, all the calls are synchronous.
Customer data is stored in a SQL Server database table called Customers. We have generic SQL Server framework code to save and retrieve data from SQL Server databases in general. This generalised framework code belongs in the outermost Frameworks & Devices shell of our Clean Architecture diagram.
OK, where do we put the connecting code, the behaviour, that utilises the generalised SQL Server framework but is about our specific database and how we store and retrieve customer data from it? Behaviour like reading the database connection string from the application-specific configuration; reading data from the Customers table, and possibly some other joined tables.
Maybe such functionality belongs to the Business Logic?
Business Logic is meant to be ignorant of data mechanisms like SQL Server. Referencing SQL data access code aware of our database type and internal schema suggests intimately knowing data mechanisms. No, we can’t put this code into the Business Logic layer.
What about the Frameworks & Devices shell? Well, it doesn’t here either. This outermost layer schematically holds generalised frameworks and is, in the context of SQL Server, concerned with generic SQL data access.
Our SQL Server database-specific code belongs to the Interface Adapters shell. This includes any auto-generated, schema-aware Object Relational Mapper (ORM) data access code.
Put into an architectural diagram, we end up with one layer of Interface Adapters:
Today has been a decent start to designing a slice of data access for a system designed with Clean Architecture. However, what if we wanted to optimise the system and include caching of data in, say, a Redis instance? How would this change our design? We’ll find out next time.
Leave a Reply
Want to join the discussion?Feel free to contribute!