Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should domain objects have dependencies injected into them?

I'm specifically referring to this question: DDD - How to implement factories

The selected answer has stated:

"factories should not be tied with dependency injection because domain objects shouldn't have dependencies injected into them."

My question is: what is the reasoning of not being able to inject dependencies in to your entities? Or am I just misunderstanding the statement? Can someone please clarify?

like image 859
n3wb Avatar asked Nov 17 '13 20:11

n3wb


People also ask

Should domain services be injected?

Dependency injection of a Repository or Domain Service into an Aggregate should generally be viewed as harmful. The motivation may be to look up a dependent object instance from inside the Aggregate.

Should every dependency be injected?

My answer is no, you do not have to do that use dependency injection every time you need to create an object. The intent behind dependency injection is to achieve separation of concerns of construction and use of objects.

Why we should not use dependency injection?

Basically, dependency injection makes some (usually but not always valid) assumptions about the nature of your objects. If those are wrong, DI may not be the best solution: First, most basically, DI assumes that tight coupling of object implementations is ALWAYS bad.

How are dependencies injected in to an object?

The injector class injects dependencies broadly in three ways: through a constructor, through a property, or through a method. Constructor Injection: In the constructor injection, the injector supplies the service (dependency) through the client class constructor.


3 Answers

Kind of old, but I really want to address this because I've been running into this a lot, and express my opinion on it:

I often hear that Domain Objects should not "depend" on things. And this is true. I often see people extrapolate this to mean we should not inject things into domain object.

That's the opposite of what dependency means. The domain shouldn't depend on other projects, this is true. But, the domain can define its own interfaces which other projects may then implement, which can then be injected back into the domain. As we all know, that's what is called Dependency Inversion (DI).

That is literally the opposite of having a dependency. Not allowing DI into the domain completely hamstrings your ability to accurately model the domain, forces odd SRP violations, and pretty much kills the usability of domain services.

I really feel like I must be the crazy one here, because I feel like everyone reads "the Domain must not have any dependencies" then thinks "being injected with something means you are dependant on it" and comes to the conclusion "therefore we can't inject dependencies into the domain.

That leaves us with the wonderful logic:

Dependency Inversion == Dependency

like image 151
Riplikash Avatar answered Oct 19 '22 06:10

Riplikash


Domain Objects aren't Factories, Repos, etc. They are only Entities, Value Objects, Domain Services and Aggregate Roots. That is, they must be classes which encapsulates the data your business domain uses, the relationships between them, and the behaviour(read modifications) that the domain can do on that data.

Repository is a pattern to abstract away the persistence infrastructure you are using. It's in DDD because it makes your app decoupled from your database, but not all DDD app need or even should use repository.

Factory is a pattern to isolate the construction logic of objects. It's also just a good practice that DDD recommends, but not really needed in all scenarios.

Domain Objects shouldn't depend on anything else, because they are the core of your app. Everything will depend on them. So keeping them free of other dependency makes a clear one way dependency chain, and reduces the dependency graph. They are the invariants, the model, the foundation. Change them, and you probably need to change a lot of stuff. So changing other things shouldn't force them to change.

like image 43
Didier A. Avatar answered Oct 19 '22 05:10

Didier A.


Domain objects should not have many dependencies.

By Fowler's Tell-Don't-Ask principle (https://martinfowler.com/bliki/TellDontAsk.html), you would want the domain objects to do as much as possible. Including having dependencies. But in Clean Code (Uncle Bob) Chapter 6, it mentions it can be a good design to have data structures operated on by procedure/function classes (services). As long as you don't have hybrid objects which combine simple getters/setters as well as more complex tell-don't-ask operations.

Fowler disagreed with thin models and called it an antipattern - AnemicDomainModel. https://www.martinfowler.com/bliki/AnemicDomainModel.html

I disagree with Fowler. I strongly agree with the following quote from another article about this Fat-Models problem: "Following this logic basically every behaviour would end up in the model classes. This is something that we know (by experience) is a bad idea. Hundreds or thousands of lines of code crammed into a single class is a recipe for disaster. Service Objects grew out of this frustration." - https://tmichel.github.io/2015/09/14/oo-controversies-tell-dont-ask-vs-the-web/

We actually have a project with fat domain models which has this exact problem. As requirements change over time and code gets more complex, a huge, fat model is quite inflexible to perform different operations and handle new requirements. Instead of adding new service workflow paths (classes) acting differently on the same simple data model, you have to make expensive, difficult refactors on the enormous, complicated domain model. It encapsulates the data and prevents anyone from modifying the data in unexpected ways but at the same time, it makes it really difficult for new workflow to manipulate the data in new ways.

like image 2
Curtis Yallop Avatar answered Oct 19 '22 05:10

Curtis Yallop