1

I think I'm missing a key part of how to actually use IoC/DI. I happen to be using the Unity container. I know how to setup a class to have it's dependencies injected and I also know how to make Unity register a type.

But what I don't know is how to actually then make use of these registrations.

So for example:

var container = new UnityContainer();
container.RegisterType<IRepository, XmlRepository>();

var service = new MyService(container.Resolve<IRepository>());

public interface IRepository
{
    void GetStuff();
}

public class XmlRepository : IRepository
{
    public void GetStuff()
    {
        throw new NotImplementedException();
    }
}

public class MyService
{
    private readonly IRepository _myRepository;
    public MyService(IRepository repository)
    {
        _myRepository = repository;
    }
}

Here I have a service layer which accepts a parameter of type IRepository. It's the container part that I seem to not be understanding.

  • Isn't the point of IoC/DI to be able to not have to manually resolve types every time I need to create an instance? In my code I'm getting the container to resolve a type, unless I'm misunderstanding how this is supposed to work, isn't the container supposed to somehow automatically (with reflection?) inject the dependency I told it to use when I registered the type? var service = new MyService(...) Is calling container.Resolve the correct way of doing this?
  • I've created a container, but how do I share this container amongst my project/code? This sort of relates to the first question. I had previously thought that there was a single place that you register types. So far the only way I can see how to get around this is to:
    • Keep registering types wherever I use them and end up with duplicated code
    • Pass the container around to every place I'm going to be resolving types
    • Neither of these ways are how I'd expect this to work
user9993
  • 5,833
  • 11
  • 56
  • 117
  • 2
    If IoC is correctly setup, the *only* service that must be manually resolved is the 'root' (there may be several). In this case the root is MyService, not IRespository. Thus, after registering MyService and IRepository, `var service = container.Resolve();` - and the IoC container will automatically resolve the IRepository dependency. (Unity also auto-resolves non-registered concrete types, so don't even need to register MyService.) – user2864740 Nov 22 '15 at 21:26
  • Related: http://stackoverflow.com/q/9501604/126014 – Mark Seemann Nov 22 '15 at 21:32
  • Related: http://stackoverflow.com/q/2386487/126014 – Mark Seemann Nov 22 '15 at 21:33
  • Passing the container around to many places means that you want to use the container as a [service locator which is an anti-pattern](http://yacoubsoftware.blogspot.com/2015/10/object-composability-another-reason-why.html). – Yacoub Massad Nov 22 '15 at 21:54

3 Answers3

6

Isn't the point of IoC/DI to be able to not have to manually resolve types every time I need to create an instance?

No, that's the point of a DI Container, but there are drawbacks to using a container as well. Favour Pure DI over using a DI Container, as this will teach you how to use Dependency Injection using only first principles.

I've created a container, but how do I share this container amongst my project/code?

You don't. The DI Container should only be used in the Composition Root (if you use a DI Container at all).

Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
  • This is a great answer, the Composition Root idea was a key idea I've been missing while learning this. – user9993 Nov 26 '15 at 16:49
1

Put your container setup in a module that runs when your program starts. You can call it from Main, for example. This is called a boot strapper.

See Dependency Injection with Unity for a good example of how to do this.

toddmo
  • 20,682
  • 14
  • 97
  • 107
1

You don't need to do new MyService(container.Resolve<IRepository>()). To get an instance of MyService, just use container.Resolve<MyService>(); it will automatically resolves the dependencies for MyService.

Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758