At which level should I apply dependency injection? Controller or Domain?
Asked Answered
D

2

6

I would like to hear from you what are de the main advantages and drawbacks in applying dependency injection at the controller level, and/or domain level.

Let me explain; if I receive a IUserRepository as param for my User, I may proceed in two ways:

  1. I inject IUserRepository direct on my domain object, then I consume User at controller level without newing objects, it means, I get them ready from the DI container.

  2. I inject IUserRepository on my controller (say, Register.aspx.cs), and there I new all my domain objects using dependencies that came from the DI container.


Yesterday, when I was talking to my friend, he told me that if you get your domain objects from the container you loose its lifecicle control, as the container manages it for you, he meant that it could be error prone when dealing with large xml configuration files. Opinion which disagree as you may have a tests that loops through every domain object within an assembly and then asks the container whether thats a singleton, request scope, session scope or app escope. It fails if any of them are true. A way of ensuring that this kind of issue wont happen.

I fell more likely to use the domain approach (1), as I see a large saving on repetitive lines of code at controller level (of course there will be more lines at XML file).

Another point my friend rose was that, imagine that for any reason youre obligated to change from di container A to B, and say that B has no support for constructor injection (which is the case for a seam container, Java, which manipulates BC or only do its task via setter injection), well, his point is that, if I have all my code at controller level I'm able to refactor my code in a smoothly maner, as I get access to tools like Auto-Refactoring and Auto-Complete, which is unavailable when youre dealing with XML files.

Im stuck at this point, as I should have a decision to make right away.

Which approach should I leverage my architecture? Are there other ways of thinking???

Do you guys really think this is a relevant concern, should I worry about it?

Diplomatic answered 12/4, 2011 at 20:34 Comment(8)
why should the User know IUserRepository ?Joella
As Im totally decided that I will not be working with an ANEMIC DOMAIN MODEL, I decided that methods like .Save(), or .Update() should be part of the entity itself, and of course delegate the hard work to those objects which main pourpose is it, it means, repositories. As I wanna also work in a decoupled way, not let my app become a huge monolitic app, I decided that the domain defines its interface for repositories, and other assemblis are due to consume it, for it to happen DI is needed to inject the concrete repository entities inside my domain objects(I use guard clauses in every ctor too)Diplomatic
@Renato Gama It sounds more as an Active Recor pattern, maybe reading about it could help. I would prefer to see IoC at work when you need services, but not in entity creation Anemic or not. I think active record pattern reach the actual entity persister via some singleton. And more, Save and Update are usually static method of the entity, not instance methods.Joella
Possible duplicate: #4835546Oscoumbrian
My thinking says that indeed its an (indirect) ActiveRecord, as I have classes representing tables in my Db... Its a non-anemic model as this entities are more capable than only storing data. Imagine that saving a new user to the db is subject to an email to administrators, then, inside .Save() I would after calling .Save() on my repository call Email.Send("message"). It makes that entity rich, not anemic!Diplomatic
Related: #1476075Oscoumbrian
Renato. A few hints to enrich your model without putting repositories into entities can be: Try to reduce getters and setters property and encapsulate more behaviour through Value objects. Regarding sending email, I would use Domain Events for that. Trigger event when you add new user to entity Customer.Users (?) collection. Then use repository to save User.Dunaway
@BacceSR, good one, never thought that way!!!Diplomatic
O
5

If you want to avoid an anemic domain model you have to abandon the classic n-tier, n-layer CRUDY application architecture. Greg Young explains why in this paper on DDDD. DI is not going to change that.

CQRS would be a better option, and DI fits very well into the small, autonomous components this type of architecture tends to produce.

Oscoumbrian answered 12/4, 2011 at 21:1 Comment(0)
D
1

I'm not into the Java sphere, but according to your details in your questions it seems like you use some kind of MVC framework (since you deal with Controllers and domain). But I do have an opinion about how to use DI in a Domain Driven architecture.

First there are several ways of doing DDD: Some uses MVC in presentation and no application service layer between MVC and Domain. Other uses MVP (or MVVM) and no service layer. BUT I think some people will agree on me that you very rarely inject repositories (or other services...). I would recommend to inject Repositories in Command (using MVC and no service layer), Presenter (if you use MVP) or Application Services (if you use service layer). I mostly use an application layer where each service get the repositories they need injected in constructor.

Second I wouldn't worry about switching between IoC containers. Most container framework today support ctor injection and can auto-resolve parameters. Now I know that you're a Java developer and I'm a MS developer, but MS Practices team has a Common Service locator that can helps you in producing code that are extremely non-dependent of which container framework you uses. There is probably some similar in the Java community.

So go for option 2. Hope I pushed you into right direction.

Dunaway answered 12/4, 2011 at 21:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.