High level image of the clean architecture from Uncle Bobs blog post:
Below is a comparison between clean architecture solutions in C# and Java. Most of the samples are in C#.
There are some similarities and some key differences between the samples. No general conclusions can be taken from this comparison since:
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.
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.
From what I can see, there seems to be some convergence and some differences in naming conventions and patterns. These differences implies that it helps to document the source of your architecture and name conventions.
We have not gone into the how different samples around how they marry frameworks but simply noted that some of them do couple the domain to a framework. From a clean architecture point of view, being overly dependant on a framework, introduce significant constraints and asymmetries.
We could improve our understanding of how clean architecture is implemented by reaching out to different organizations implementing clean architecture, but that goes beyond the scope of a simple blog post.
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.
Comments