2

normally, I'll use a dependency injection container (unity) in c# like this example:

class SomeClass
{
    private readonly ILogger _logger;

    public SomeClass()
    {
        _logger = DependencyContainer.Resolve<ILogger>();
    }

    public void DoSomething()
    {
        var someOtherClass = DependencyContainer.Resolve<...>();
        someOtherClass().whatElseEver();
    }
}

Yesterday, I've read some articles about correct dependency injection with a di container. After this, I know that my example is totally bad. This is not dependency injection this is just something like a service locator.

Okay, how to solve this? I think with constructor injection you can solve this problem easily:

class SomeClass
{
    private readonly ILogger _logger;
    private readonly ISomeOtherClass _someOtherClass;

    public SomeClass(ILogger logger, ISomeOtherClass someOtherClass)
    {
        _logger = logger;
        _someOtherClass = someOtherClass;
    }

    public void DoSomething()
    {
        _someOtherClass().whatElseEver();
    }
}

Now I have the correct implementation of the dependency injection principle. But how to wire up all these dependencies? I have a caller class which resolve all the required decencies of the class "SomeClass":

class SomeClassCaller
{
    public void DoSomething()
    {
        var logger = DependencyContainer.Resolve<ILogger>();
        var someOtherClass = DependencyContainer.Resolve<...>();

        var someClass = new SomeClass(logger, someOtherClass);
        someClass.DoSomething();
    }
}

But this example still use a dependency container as a service locator, which is bad. In nearly every article about this, I've read, that the dependency container should only be used, at the application root/entry points, is this correct?

That means, no class should have the ability the resolve some dependencies with a "service locator" on the fly, like the logger. I've to inject the ILogger into nearly every class through the constructor, to avoid this problem, correct? This way feels really bad, if I take the ILogger through maybe 10 classes into every constructor, isn't it?

So, I've to use a dependencies container only, if I've a complex dependencie graph?

Can someone give me an example how it looks like, if you use a dependency container, only at the root of an application?

Ruben Bartelink
  • 59,778
  • 26
  • 187
  • 249
Marcel Hoffmann
  • 973
  • 1
  • 8
  • 15
  • Please see [this](http://stackoverflow.com/questions/6277771/what-is-a-composition-root-in-the-context-of-dependency-injection) answer. Also there are lots of such questions on SO about this exact same problem. – kayess Feb 26 '16 at 11:49
  • You seem to have a good handle on stuff in general. One thing you must do this instant is to buy Mark Seemann's DI in .NET - you won't regret it; it will fill in lots of gaps in your thought process aound this and software architecture in general. Now, wrt your actual question, I'm not certain what you're asking but I have a hunch that this article may be useful for you in showing how one separates essential parameters from ones that are not directly useful to the consuming class: http://docs.autofac.org/en/latest/advanced/delegate-factories.html – Ruben Bartelink Feb 26 '16 at 16:48

1 Answers1

4

If SomeClassCaller needs SomeClass, inject it:

public class SomeClassCaller
{
    private readonly SomeClass someClass;

    public SomeClassCaller(SomeClass someClass)
    {
        this.someClass = someClass;
    }

    public void DoSomething()
    {
        this.someClass.DoSomething();
    }
}

This is an example of a Concrete Dependency. Commonly, though, you could let SomeClass implement an interface, and then inject that interface into SomeClassCaller, instead of the concrete class.

In the Composition Root you can wire up your object graph:

var scc = new SomeClassCaller(
    new SomeClass(
        new MyLogger(),
        new SomeOtherClass()));

You don't need a DI Container to do this, but you can use one if you like.

Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
  • Thank you this helps me a lot. In our company, we have done dependency incjection using a IoC container totally done, we're using an IoC container as an service locator. Now, it's clear for me, how to use an IoC container, thanks. – Marcel Hoffmann Feb 26 '16 at 19:58