3

I was wondering how far I should take my IoC implementation in terms of loosely coupling my application. I am using constructor injection in my MVC controller but wondered if I should also be resolving all my other dependencies in the controller instead of newing up objects. For example if I was to create a new User object within a controller method would I use?

var user = new User();
var user = myContainer.Resolve<IUser>();

I like the idea of breaking my dependency on User but is that going too far and could possible make my code harder to read?

Cragly
  • 3,554
  • 9
  • 45
  • 59
  • 1
    [Similar question](http://stackoverflow.com/questions/4835046/why-not-use-an-ioc-container-to-resolve-dependencies-for-entities-business-objec) – Sebastian Weber May 24 '12 at 11:51
  • 1
    When you call the container from within your services, you are doing the Service Locator anti-pattern. Read this why you shouldn't do this: http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx. – Steven May 24 '12 at 12:49
  • Does that mean it is ok to new up objects? or should those dependencies be injected in the constructor as well. I thought injecting a lot of dependencies in the constructor was not a good idea hence the service locator pattern. At the moment, I am newing up a lot of objects in my HomeController. How do I remove the depencencies then? – Cragly May 24 '12 at 13:25
  • Maybe [this article](http://misko.hevery.com/2008/09/30/to-new-or-not-to-new/) about newables and injectables can help. – Sebastian Weber May 24 '12 at 15:27
  • It is *absolutely* ok to new up objects manually. Avoiding the "new" keyword is *not* the intent of using DI. – Phil Sandler May 30 '12 at 19:22
  • 1
    You should separate data and behavior. New up objects that contain data and (DTOs) let objects that contain behavior (services) be injected. – Steven May 30 '12 at 20:13

1 Answers1

5

This is a very good question, when you read and hear about DI it makes sense and this is the next natural conclusion.

First Steven's point is correct you should not pass the container around. If you need to construct IUser on the fly and it needs to be abstract you should rather inject an Abstract Factory.

Sebastian also posted a good link.

I actually wrote about this in an answer I posted here.

The bottom section of the post:

Not every object and dependency needs or should be dependency injected, first consider if what you are using is actually considered a dependency:

What are dependencies?

Application Configuration
System Resources (Clock)
Third Party Libraries
Database
WCF/Network Services
External Systems (File/Email)

Any of the above objects or collaborators can be out of your control and cause side effects and difference in behavior and make it hard to test. These are the times to consider an Abstraction (Class/Interface) and use DI.

What are not dependencies, doesn't really need DI?

List
MemoryStream
Strings/Primitives
Leaf Objects/Dto's

So in your particular case it really depends on what happens when IUser is constructed also whether you actually need to substitute it with different implementations. If this is not the case and User has only simple types with no external dependencies or side effects just new it up.

Consider what happens when you call new User(), look at the graph below, if it causes other objects to be created and looks like something in the graph below consider IoC.

A cascading dependency object graph:

Dependency graph

In this example new on the object either requires or creates a whole bunch of other dependencies. It is most likely out of your control what those dependencies are or do.

When your object is a simple dto it doesn't suffer this problem and IoC is likely not so much required.

Community
  • 1
  • 1
Andre
  • 3,717
  • 4
  • 25
  • 29
  • I decided to take your advice and examine each objects merits for DI. Thanks for the detailed answer. – Cragly May 31 '12 at 08:44