2

While reading about IoC/DI containers, I read in a few places (e.g. here and here and here) that the container should ideally be used only at startup.

Does this mean you need to always rely on the container injecting the parameters to the constructors of the objects you need to resolve? Even then, do you not still need the container to create those types?

What about classes that use an instance of a central service (typically a singleton) which is registered in the container?

What about classes whose constructors require parameters of types that are not registered in the container?

Community
  • 1
  • 1
Gigi
  • 28,163
  • 29
  • 106
  • 188

1 Answers1

3

While reading about IoC/DI containers, I read in a few places (e.g. here and here and here) that the container should ideally be used only at startup.

They mean that you configure the container and register all components at application startup (or otherwise very early).

It makes sense, because typically you have a one or a few root objects (e.g. instantiated first by the container) and from there on the container should take of resolving dependencies if all of them are configured correctly.

In other situations you have to request the root objects from the container (e.g. a console or Windows Service application) because there's no way for it to integrate with the platform at startup like it can do for example for ASP.NET WebApi or MVC (well, no way excepting assembly instrumentation).

More exactly, you need to call Resolve or GetInstance (or whatever the DI framework supports) for the root objects in these situations.

What about classes that use an instance of a central service (typically a singleton) which is registered in the container?

All DI containers support per-container lifetime, which is what a singleton basically gives you. So, you can register a singleton instance in the container with a lifetime matching that of the container and then inject that instance where you need it.

EDIT: as it turns out I got this backwards. You have here the options of either registering these classes with the container and let it do the injection, or call Resolve manually. However, as I said in the comments, some people consider service locator to be an anti-pattern. I think that if you don't abuse it and use it when it's more trouble than worth to register with the container, then do it.

What about classes whose constructors require parameters of types that are not registered in the container?

I think that's the point of DI. If you want a component to not use DI, then don't register it and instantiate it as usual, via new. Otherwise, if unresolved dependencies are detected by the DI container then it will most likely throw. And it should throw so you can see the error and correct it.

Marcel N.
  • 13,726
  • 5
  • 47
  • 72
  • Just to clarify the middle part - since I think that's the one I didn't fully understand when I asked the question - is it okay to call Resolve() in some class that has a dependency (thereby using the container post-startup)? I thought this was the whole point of IoC/DI, but this whole startup thing got me confused. – Gigi Aug 14 '14 at 10:29
  • @Gigi: Yes, it is OK to call `Resolve` (known as the Service Locator pattern) in cases when the DI container cannot integrate completely with the infrastructure. The most relevant example is a console application, where the main method is called by the platform. – Marcel N. Aug 14 '14 at 10:33
  • @Gigi: I think I misunderstood your question. It is not nice to call `Resolve` in a class that has a dependency unless that class is not a registered component in the container. If it's outside of it then you're subject of the service locator pattern and some people dislike that ([this](http://stackoverflow.com/questions/22795459/is-servicelocator-anti-pattern), for example). What I was saying is that it is not OK to keep registering types in the container after application startup. You could resolve them manually if that's what you have to do. – Marcel N. Aug 14 '14 at 10:57
  • OK, why is it not nice to call Resolve in an unregistered class? – Gigi Aug 14 '14 at 11:37
  • @Gigi: No, I meant that as a semi-joke. It's just some people consider service locator to be an anti-pattern. Calling Resolve means you're using the DI container as a service locator, so somebody might have something to say about that. I'd rather register with the container than calling `Resolve` but if that's not possible then I guess you can resolve it manually. – Marcel N. Aug 14 '14 at 11:43