1

I have read a bit about DI and DI containers that manage the DI for you.

Basically you create your classes that have dependencies, and provide a way for injection using the constructor or setter methods. You then tell your DI container, which concrete classes you want to use for wiring everything together. Lastly you make a call to some kind of service locator, that resolves all the dependencies for you and gives you the complex object with just one line of code.

I have never used a concrete DI container implementation, so i wonder how a DI container handles the objects at the lowest level. These objects most likely have to be configured using concrete (coded) values, or the content of a configuration file. Take this for example:

class FooDao {
    public FooDao(DBConnection db) {...}
}

class ConcreteDBConnection : DBConnection {
    public ConcreteDBConnection(String url, int port, String user, String pw)
    {...}
}

You would tell your DI container (using annotations, XML files, or something else), that you want to instantiate your FooDao objects with a ConcreteDBConnection object. But how do you tell your DI container the concrete values needed for your database connection? What if the concrete values need to be calculated first (encrypting locally stored database connection information for example)?

I know this is a very general question, but the articles i read about DI container were also very general and this point really confused me. A short explanation how a arbitrary popular DI framework does this would be enough to answer my question.

Luca Fülbier
  • 2,641
  • 1
  • 26
  • 43
  • 2
    See [Dependency-injection anti-pattern: Injecting runtime data into components](https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=99&month=11&year=2015) and [Why do we need Abstract factory design pattern?](http://stackoverflow.com/q/2280170/181087) – NightOwl888 Jun 30 '16 at 14:49

1 Answers1

1

If you're asking how to use a popular DI container, there are a lot of articles on using Castle Windsor (such as http://ardalis.com/getting-started-with-castle-windsor) and the concepts will be familiar when you try other DI frameworks. Castle Windsor is really good though -- it's a great place to start.

If you're asking how DI containers work -- that's a longer discussion, but the basics are: 1. You create a container of some kind, using your framework. Normally as simple as var container = new Container(); 1. You register a mapping of interface ("service") to concrete classes with the container. Some frameworks have some magic to do a lot of this for you, like the most common requirement: if you have an interface IFoo and only one resolution, the class Foo, then it can be automatically registered for you (iirc, Autofac does this?) 2. You ask your container to resolve interfaces -- which it maps back to classes. During resolution, your container can inspect constructors of the provided concrete classes and attempt to resolve parameters based on their types; similarly, it can set properties based on their types and the known registrations.

daf
  • 1,289
  • 11
  • 16
  • I am asking how i inject concrete values. Registering the concrete classes for an interface is pretty straight forward, but in every article i read about Di containers, they end up with "leaf classes" that have no dependency whatsoever. I found that to be a bit odd, since you will have a lot of configuration data that has to be injected throughout your object hierarchy. – Luca Fülbier Jun 30 '16 at 14:32
  • 1
    If there is configuration data to inject in a lot of places, we'll usually have an interface like `IApplicationConfig` which can be injected via constructor. The concrete implementation of that could be manually registered (for instance, Windsor can do a singleton registration) or you can play tricks with the DictionaryAdapter to get hold of configuration from your app.config. – daf Jun 30 '16 at 14:34
  • Bear in mind that registrations don't have to be transient -- they can have life-cycles dependent on thread, http request, or application lifetime. – daf Jun 30 '16 at 14:35
  • So there are possibilities to register classes that you can initialize beforehand in code? The IApplicationConfig approach seems to be a good way to do things, at least if the DI container provides the option to specify which concrete ApplicationConfig you want for a specific class (Or you simply create a ApplicationConfig class that manages ALL configuration value loading). – Luca Fülbier Jun 30 '16 at 14:45
  • Yeah, how you do so depends on the DI frawework you're using, but Castle Windsor, for example, allows something like: `container.Register(Component.For().Instance(myT));` You can also register a component with a factory method to fully take care of construction and you can hook into destruction to take care of unmanaged resources. Take a look at the Castle Windsor documentation / examples -- it's a good place to start. – daf Jun 30 '16 at 14:49
  • Seems like the "wiring up" code of a program using a DI container can get pretty messy, if the program is big :-) – Luca Fülbier Jun 30 '16 at 14:56