In a former life, I wouldn't think twice about using dependency injection to put behavior into a domain object. But the more I learned about traditional DDD, the more I found that it was considered "taboo" to inject things into your entity objects. Obviously injecting behavior into domain services was okay, but entities were special. Of course, this topic is still a matter of debate among DDDers and there are people on both sides of the line.
Last night, while I was reviewing some CQRS principles, I decided to watch the original video recording that introduced me to DDDD. I've seen it a few times, but something stuck out at me regarding DI and entity objects. Specifically at 15:30 in the video Greg talks about DI: "My rule of thumb when it comes to things like dependency injection is that coupling is okay if it's at the same layer."
This does not mean that we are free to inject anything that we want into our entity objects. For example, it is not okay do inject an EmailGatewayService or something like that into our entity—because EmailGatewayService wouldn't have anything to do with our domain—it's a purely infrastructure concern. Instead we should send a message to the EmailGatewayService. It does mean that we can inject *domain services* for the domain into an entity object.
ORMs vs. DI
I appears that one of the biggest deterrents to using DI with entity objects is that, in traditional DDD, your entity objects are hydrated using an ORM. Hooking into the hydration process isn't very fun and can be a little sticky depending on your ORM of choice. I've worked through this before and, while possible, isn't a particularly elegant solution and very often feels like a hack.
But in DDDD, on the other hand, dependency injection is quite easy. Because you're dealing with true POCO/POJO object and you control the full object lifecycle and rehydration via the event stream, you can easily inject domain services into your entities.
Flip Flop?
Does this represent a shift in my previous thinking? Absolutely. But the worst thing that we can do as developers is to blindly cling to a convention. As part of our growth we should be able to re-evaluate decisions in light of new understanding and be able to make more educated decisions as a result. In other words, yes, I changed my mind--but only because of a new understanding, a new point of view, a new paradigm.
"And the end of all our wanders will be to arrive where you started and to know the place for the first time."