On a high level eShopOnWeb uses clean architecture.
The main idea of clean architecture is that the solution is spilt into different projects (or layers) and that the domain project is at the centre with all other projects pointing into it. Other projects typically include an Infrastructure and UI project. Importantly these point into the domain project via interfaces not concrete dependencies.
Concrete dependencies on things like Entity Framework and Redis are defined in the Infrastructure project. Dependency injection is a fundamental concept in clean architecture and is used to inject these dependencies at runtime.
The diagram below (taken from the accompanying eBook for eShopOnWeb) shows a typical clean architecture setup…
The main proposed benefits of clean architecture is that because its heavily abstracted its easy to swap out implementations and also easy to test. I’ve definitely seen these benefits when I’ve used it BUT unfortunately these benefits come with huge cost in terms of extra complexity of the overall solution.
One thing in particular with clean architecture is that it’s so abstracted there’s extra cognitive work required to actually know where in the application something is actually done and how things ‘fit together’.
As clean architecture separates code by technical not functional concern it can often have really low functional cohesion and so code for any one use case is scattered all over the place. For example below shows the files (note.. some of these are needed by alternative architectures too) involved in the Get My Orders use case in eShopOnWeb. To get an end to end understanding of how this use case actually works I have to navigate through a lot of files and projects.
Click on the image for a larger view in a new window…
I find this kind of solution architecture very unsatisfying to work with as a developer and definitely notice myself using ‘Go to Implementation’ a lot when reviewing systems which use it.
Of course having so much separation of concerns also means debugging can be harder, onboarding can be harder, PRs can be larger as often a lot of files to change, tracking bugs back to check-ins can be harder, documenting the system can be harder and yes actually adding or changing features can IMHO also be much harder.
Vertical slice architecture as an alternative to clean architecture?
IMHO vertical slice architecture is a much more pragmatic and developer friendly macro-architecture.
With VSA we aim to limit abstractions and have high feature cohesion by placing concrete code which corresponds to any one feature or use case together. For example… in the below still from Derek Comartins Restructuring to a Vertical Slice Architecture video on YouTube he has restructured the eShopOnWeb code for the Get My Orders use case shown above so that it is all together…
And the code for Derek’s refactor is available on the accompanying blog post on his site.
It might not be one for the ‘purists’ among us but IMHO having all (or most) of the code for a particular use case together (doesn’t necessarily have to be in the same file) is much easier to work with than having to constantly navigate around layers of abstractions and multiple projects as is often the case with clean architecture.
Of course the above is just my opinion and using clean architecture is definitely not ‘wrong’… it’s extremely popular online and because context is everything some projects will absolutely benefit from the rigid structure it provides. In particular many architects feel it helps less senior developers into the ‘pit of success‘ which basically means its an architecture which makes it harder for them to do the wrong things due to how structured and prescriptive it is.
What do you like to use in your apps? Clean architecture, vertical slice architecture or something else?