Clean Architecture (DDD) Why are domain objects (DB Entitites) and DbContext in separate projects?

609 views Asked by At

I understand the need for abstraction and separating concerns and unit tests, however, it seems to me that separating entities and context into 2 projects is slight overengineering?

I could be missing something really, but is this because you want to be open for different ORM-s?

Much thanks for the clarification.

1

There are 1 answers

0
ssmith On

The main reason I prefer to have Infrastructure in a separate project, rather than just a separate folder, from the domain model (Core project) is simple: enforcing my design via the compiler.

I have a design rule, which is basically the Dependency Inversion Principle. Don't depend on low level implementations (such as those found in Infrastructure), instead depend on abstractions (interfaces). Also, don't have your abstractions depend on details; have details depend on abstractions. The details of how and which infrastructure is being used for a given abstraction are in the Infrastructure service implementations.

Abstractions say what; implementations say how.

What: I need to send an email. ISendEmail interface

How: I want to do it using the SMTP protcol SmtpEmailSender class (implements ISendEmail)

How: I want to do it using a SendGrid API SendGridEmailSender class (implements ISendEmail)

So, in a single project, how would you ensure that the implementations depend on the interfaces, and not vice versa?

How would you ensure your domain classes didn't directly reference or use Infrastructure types?

I'm not aware of a way to do this.

But if you put them in separate projects, and you have the implementation details project depend on the abstractions-and-models project, you now have solved the problem. The compiler WILL NOT ALLOW the Core project to reference anything in the Infrastructure project, because it would create a circular dependency.

This constraint helps developers do the right thing and keeps them falling into the pit of success even if they don't completely grok how the dependency inversion principle works or why it's important.

And I've never found 3 projects (Core/Infra/UI) to be overengineering for any non-demo app I've built for real work. It's only 3 projects.