views:

50

answers:

2

Let's say I have some class with dependency injected:

public class SomeBusinessCaller {
   ILogger logger;
   public SomeBusinessCaller(ILogger logger) {
       this.logger = logger;
   }
}

My question is, how do I instantiate an object of that class? Let's say I have an implementation for this, called AppLogger. After I say

ObjectFactory.For<ILogger>().Use<AppLogger>();

how do I call constructor of SomeBusinessCaller? Am I calling

SomeBusinessCaller caller = ObjectFactory.GetInstance<SomeBusinessCaller>();

or there is a different strategy for that?

+2  A: 

Depending on which DI Container you use, then yes: ask the container to provide you with an instance of SomeBusinessCaller.

The container should use auto-wiring to automatically figure out that the SomeBusinessCaller requires an instance of ILogger, and since AppLogger is registered, it can satisfy that requirement.

However, don't use the DI Container as a static Service Locator.

Instead, you should let the DI Container compose your entire dependency graph in one go in the application's Composition Root.

Mark Seemann
I understand that auto-wiring must figure out requirements of the class, but calling side still needs to provide a parameter for the class constructor
chester89
The container supplies the parameter by creating an `AppLogger` instance for you. You shouldn't have to supply it yourself.
Mark Seemann
so, parameterless constructor will do the job?
chester89
You should only use default constructors for those classes where it makes sense. If `AppLogger` takes dependencies in its constructor, just register those with the container as well. The container will resolve all dependencies until all are satisfied (or it runs into something that's not registered).
Mark Seemann
+1  A: 

The code which uses caller does not live in a vacuum. Instead of assuming you need to create an instance of SomeBusinessCaller yourself, simply declare a dependency on it:

public class SomeOtherClass
{
    public SomeOtherClass(SomeBusinessCaller caller)
    {
        // ...
    }
}

The container will figure out that SomeBusinessCaller requires an ILogger, and it will automatically provide an instance of AppLogger.

And, when something needs an instance of that class:

public class YetAnotherClass
{
    public YetAnotherClass(SomeOtherClass other)
    {
        // ...
    }
}

If you follow that logic for all the objects you write, eventually you will have exactly 1 object for which you actually request an instance:

public static void Main()
{
    // ...Initialize ObjectFactory...

    var compositionRootObject = ObjectFactory.GetInstance<YetAnotherClass>();

    compositionRootObject.DoYourThing();
}
Bryan Watts
I think I get what you're saying. So, I need to set up container and then instantiate only one object via GetInstance call? All its dependencies will be satisfied automagically by the container?
chester89
Exactly. If you need to create an object *after* you have resolved the root object, you should register a factory with the container and take that in the constructor of the object which needs to create the instance.
Bryan Watts