I am doing an MVC project with structuremap as an IOC container. We are doing TDD, and I want to set up my dependencies so that its easy to work with, and so that its easy to test.
Ho开发者_开发百科w should I best set up the graph of dependencies for the below fictional illustrated graph ?
- ApplicationController
- Controller
- AuthenticationService
- UserRepository
- AuthenticationService
- Controller
Do you inject the userrepository on the controller, and further from the in the authenticationservice? And what if the graph is deeper - will you not get a lot of dependencies starting on the controller?
If you have a dependency on you applicationcontroller, do you also inject that on the controller, and that way up on the base?
If I let the container resolve the instance somewhere in the middle of the graph, I would have to setup the container for testing? Is that a good thing to do, or best avoided?
Is there another way, that I am not seeing?
Your dependency graph looks fine. As illustrated, each class only has one dependency
- ApplicationController depends on Controller
- Controller depends on AuthenticationService
- AuthenticationService depends on UserRepository
I realize that this is a simplified view, and that your real production architecture will be much more complex, but the nice thing about DI (and Constructor Injection in particular) is that it makes violations of the Single Responsibility Principle so obvious.
Whan a class starts getting too many dependencies, it's a sign that you should refactor to an Aggregate Service.
The final dependency graph may be huge, but each class only depends on a few abstractions, so from an architectural point of view, this is not a problem.
You should never have to resolve the instance in the middle of the graph. Resolving is something that you do in the Composition Root, and (theoretically) only once.
When it comes to unit testing, you shouldn't have to use a DI Container at all.
Not sure how your applicationController relates to your controller but in general, your controller would have a dependency on your service and your service would have a dependency on the repository.
e.g.
public MyXyzController
{
public MyXyzController(IAuthenticationService authenticationService){...}
}
public class AuthenticationService : IAuthenticationService
{
public AuthenticationService(IUserRepository userRepository){...}
}
In this way, your IOC container will automatically resolve all dependencies when you ask for (ie resolve) the controller.
精彩评论