32

When I used IoC Container in my last project, I ended up with anemic entities and most of my business logic in Stateless Services.

I have seen projects written by other developers that utilize "Inversion of Control" and they are always "Anemic".

Since "Anemic Domain Model" is anti-pattern, is it possible to use IoC and Rich Domain? Are their any good examples, open source projects that do that?

4
  • I think we'd need to see some specific examples of your particular case to help out. May 1, 2011 at 9:14
  • 1
    Sorry, I meant code snippets :) May 1, 2011 at 9:25
  • Service != Domain Model. Arguably the more "anemic" you make a service, the easier it is to understand, test and keep bug free.
    – R. Schmitz
    Oct 7, 2020 at 20:15
  • Also, anemic domain models are not object oriented, but that doesn't make them an anti-pattern. On the contrary, I have never seen an anemic domain model which isn't clean and easily understandable code.
    – R. Schmitz
    Oct 7, 2020 at 20:26

4 Answers 4

11

For starters: DI and IoC are not synonyms. I am sorry but I must point that out (it seems to me that you think they are).

As for your inquiry... Well, Dependency Injection is just a tool. How you are going to use this tool is completely separate thing. There are also other tools (design patterns) that could add up to the problem. For example, I feel that wide adoption of MVC pattern is one of the key ingredient to forming Anemic Domain Model anti-pattern: Controllers (in simpler applications, in more complicated ones that would be additional Service Layer) take on responsibility for validating business rules, enforcing them as well as transforming DB entities into something useful, whereas Business Layer turns into simple Data Access Layer that is plain ORM with one-to-one mapping to database entities.

Certainly it is how you design your application — you can create a correct Domain Model if you want, and all these IoC, DI, MVC do not stop you. What could stop you is your team. You somehow need to convince them to use the right path and it might be hard as many Software Developers do not have strong architectural background.

4
  • I'll add to this that perhaps you could take a peek at the DDD approach espoused by Eric Evans et al. May 1, 2011 at 9:42
  • 1
    I did read Eric Evans' book. It is good for general methodology and ubiquitous language, but somewhat lacking in real-world examples.
    – Mag20
    May 1, 2011 at 9:47
  • Thanks for pointing out the difference between DI and IoC. I think the issue had more to do with IoC then DI. Changed the question to reflect that.
    – Mag20
    May 1, 2011 at 9:54
  • In my experience with DI frameworks/containers (Spring DI, CDI, Unity), they indeed do stop you from creating a "correct Domain Model", which to me means that developers should not be constrained from using true (ie, stateful) objects. But DI doesn't really support that.
    – Rogério
    Jun 28, 2015 at 16:14
8

Most (if not all) applications are a mix of infrastructure and domain concerns. When you reach a certain level of complexity you'll make it easier to manage if the domain is separated from the infrastructure so that it is easier to reason about and can evolve independently.

Of course the domain model still needs to communicate with the rest of the system and usually this will be with stateless services (which are part of the domain) that have infrastructure concerns (such as database access) injected into them. Using an IoC container doesn't remove this dependency, it moves its configuration into a separate area - again making it easier to reason with and maintain.

The entities are storing state and should be responsible for the business rules. If your services are enforcing all the invariants and other business rules then it's likely that logic is in the wrong place.

Now if you've got the logic in the right places and yet have still ended up with services that are no more than wrappers around infrastructure things and entities that are just property bags then it's very likely that the domain isn't complex enough to justify the overhead of its own model. Just about anything you'll read about DDD will contain a disclaimer that its really only intended for complex domains, but this seems to be all too often forgotten.

0
7

Go to the source. Start with Fowler's piece on Anemic Domain Models. He references Eric Evan's Domain Driven Design as an example of good practice. The source code for that is here. Download it.

Observe that it uses Inversion of Control (search for @Autowired), and has service classes (BookingService), and "business process" classes (e.g. ItineraryUpdater).

Fowler's original article starts the trail to the example you are looking for.

7
  • That sample app, in fact, is not in accordance with DDD as described in the book. A specific contradiction with the book is that is it utterly violates the concept of "infrastructure", by allowing it to contain domain-specific code; for example, the VoyageRepositoryHibernate class, which was put in the infrastructure layer but actually depends on the domain layer.
    – Rogério
    Jun 28, 2015 at 16:08
  • Yes, the book says on page 73 that the infrastructure layer is "below" the domain layer and "it should have no special knowledge of the domain it is serving". This just never made sense to me. Consider a project that has two VoyageRepository implementations: VoyageRepositoryHibernate and a VoyageRepositoryJDBC class. Their implementations are necessarily very different, and technology specific. Do these belong in the domain layer? Or the infrastructure layer? In our code, according to the book, we do it backwards: the infrastructure layer can reference the domain layer, but not vice versa.
    – jamie
    Feb 5, 2016 at 22:45
  • They belong in the domain layer, yes. The JDBC-based implementation would contain SQL code tied to tables and columns in the application database, which are specific to the domain. Putting any domain- or application-specific code in the infrastructure layer is just wrong, as "infrastructure code" should only be used to solve technical concerns, and should (ideally) be fully reusable between different applications and domains. The solution to having "low-level" code (eg. SQL) in the domain layer is not to move it out entirely, but to implement it on top of better infrastructure, such as ORM.
    – Rogério
    Feb 7, 2016 at 12:19
  • To me, the implementation of save(MyDomainObject foo) is a purely technical concern. YMMV.
    – jamie
    Feb 9, 2016 at 0:47
  • Only if it does not lead you to violate the fundamental rule of a layered architecture: a lower layer cannot depend on a higher layer. So, if you implemented save(foo) with code that is subject to change when the domain model changes (for example, if a new attribute is added to MyDomainObject), then it must (by definition) belong to the domain layer; otherwise, you just can't talk about having "layers" anymore.
    – Rogério
    Feb 9, 2016 at 15:00
7

is it possible to use IoC and Rich Domain? Are their any good examples, open source projects that do that?

I assume you mean DI instead of IoC, and the project you worked on uses a DI container like Spring. IoC has two main flavors: DI and Locator pattern. I don't see why the Locator pattern should be a problem, so let's focus on DI.

I don't think it's possible, or at least would be very impracticle. The main aspect of DI containers is that they control the creation of objects when they inject them into others ("managed objects"). The set of managed objects that is alive when the projects runs is independent from which domain items exist in your project but depends on how objects are wired and which scopes (singleton, prototype) are assigned to them.

This is why you don't want to let the DI container manage your domain objects. But if you create objects manually (with new), you can't get other objects injected to your domain objects. (Leaving potential work-arounds with manual wiring aside.) Since you need these injections to replace implementations with others, you can't replace the functionality of rich domain objects using DI. Hence, you will not want to place functionality into domain objects, or you'd lose the features of the DI.

I don't see how a hypothetical DI container could work that doesn't manage your objects, and none of the existing implementations allows that. So it's fair to claim that DI relies on managing objects. It will therefore always tempt you to split potential Rich Domain objects into one anemic class and one or several transaction script classes.

1
  • This answer really hits the nail on the head when it comes to the tension between a Rich Domain Model and and Dependency Injection.
    – jmrah
    Aug 25, 2015 at 18:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.