Assertfail

Clean Architecture Comparison

02 Dec 2023

High level image of the clean architecture from Uncle Bobs blog post:

The Clean Architecture image

Below is a comparison between clean architecture solutions in C# and Java. Most of the samples are in C#.

Note also that the solutions I’ve picked are somewhat arbitrarily chosen. Some have a lot of attention on GitHub while I’ve kept my eyes on others for a longer time.

Sample Use of Libraries/Structure Grouping/Vertical slice
@CanerPatir/aspnet-core-clean-arch WebApi, Infrastructure, Application, Domain libraries Per use case grouping of folders in Application and WebApi
@ivanpaulovich/clean-architecture-manga WebApi, Infrastructure, Application, Domain libraries Per use case grouping of folders in Application and WebApi
@jasontaylordev/CleanArchitecture Web, Infrastructure, Application, Domain libraries  
@mattia-battiston/clean-architecture-example Groups entities and use cases in core project configuration, entrypoints, dataproviders, core libraries
@ardalis/CleanArchitecture Web, Infrastructure, UseCases, Core libraries Per use case grouping in Application
@dotnet-architecture/eShopOnWeb Web, PublicApi, Infrastructure, ApplicationCore libraries Aggregate, “Service”
@kgrzybek/modular-monolith-with-ddd Api, Infrastructure, Application, Domain libraries Per subdomain projects

There does not seem to be a clear consensus around the naming of layers. Some projects are too simple to get into grouping into slices or subdomains, some of the projects (most notably modular monolith with ddd) shows how a more fleshed out structure could look (in the case that your web api only implements one bounded domain).

Sample Command handler interface/base class Query handler interface/base class
@CanerPatir/aspnet-core-clean-arch ICommandHandler IQueryHandler
@ivanpaulovich/clean-architecture-manga IOutputPort/Named IOutputPort/Named
@jasontaylordev/CleanArchitecture IRequestHandler IRequestHandler
@mattia-battiston/clean-architecture-example - -
@ardalis/CleanArchitecture ICommandHandler IQueryHandler
@dotnet-architecture/eShopOnWeb - Specification
@kgrzybek/modular-monolith-with-ddd ICommandHandler IQueryHandler

The solutions presented use a couple of different patterns. Most of the solutions use classes per action while some (such as eShopOnWeb) group all of the actions into one class per entity (in this case called service-classes).

We see that @jasontylerdev, @kgrzybek, @ardalis in their samples marries the framework MediatR. In the case of @ardalis we note that he marries the framework Ardalis.SharedKernel in his sample. In the case of the dotnet architecture sample eShopOnWeb that solution marries Ardalis.Specification. We can only echo what Robert C. Martin writes in his book Clean Architecture on page 292 that you have a extraordinarily asymmetric marriage when you take on a direct dependency on a framework. @ardalis is aware of this fact and write in the about text on his SharedKernel project the following:

Some useful base classes, mainly used with the CleanArchitecture template. Also, a template to make your own SharedKernel nuget package.

Sample Anemic domain entities
@CanerPatir/aspnet-core-clean-arch No
@ivanpaulovich/clean-architecture-manga No
@jasontaylordev/CleanArchitecture Yes
@mattia-battiston/clean-architecture-example Yes
@ardalis/CleanArchitecture No
@dotnet-architecture/eShopOnWeb No
@kgrzybek/modular-monolith-with-ddd No

The use of anemic domain model is not uncommon. A dissenting view from what Martin Fowler teaches is that you should embrace manipulating data instead of coupling data and behavior as seen in the book Data Oriented Programming. Note also that even though the domain might be too simple in many cases, I’ve given the authors the benefit of doubt.

Tags


Comments

Do you want to send a comment or give me a hint about any issues with a blog post: Open up an issue on GitHub.

Do you want to fix an error or add a comment published on the blog? You can do a fork of this post and do a pull request on github.