4

This is a follow up question to the following post: Injecting dependencies (DI) in c++ applications

In a system that uses DI, someone, somewhere should be responsible to create the various objects and "wire" them. I find it difficult to figure out who should do this. I read about one option that it should be the "root class". However, in that case it seems that the root class might be responsible for creating a very large number of objects.

I though of an option to use smaller builder classes that will be used the root class - is that a good way to do it?

Note: I tagged 'C++' in this question because I am developing in C++. I am not sure if it makes any difference to the answer.

Erik Sapir
  • 231
  • 1
  • 3
  • 5
  • 2
    If you're using a DI Container, the DI Container is responsible for figuring out what the needed dependencies are. If you're injecting dependencies through the class constructor, the caller of the constructor is responsible. – Robert Harvey Mar 26 '14 at 20:19
  • I am not using the DI container. This is my question - who should be the caller to the constructor. If the rule of thumb is that collaborators should only be injected and not constructed in the class, someone else should create them. Where it should stop (In the root class or before) and how the creation should be handled? – Erik Sapir Mar 26 '14 at 20:21

2 Answers2

3

It depends on the intended lifetime and ownership of your objects. To construct an object of type C you need an object of type D. Shall this D object have the same lifetime as the C object? Then it makes sense to construct the D object at the same scope where the C object is constructed. Shall the D object live longer than C? Then you should construct it outside before and pass it to the function which constructs C.

Given your objects B, C and D shall have the same lifetime, and that lifetime shall be controlled by an object of type A, it makes sense to let A construct them and "wire" them. If the D object shall live longer, it must be constructed (and destroyed) outside of A.

If you note that A gets too much responsibilities by managing other, dependent objects of B, A might use a "BFactory" class for this purpose, like @gnat suggested as a response to your other question. And if you want to avoid A having to construct that factory, this factory could also be injected into A through an interface "IBFactory".

And if your system gets really large, because you have to not four but 400 classes to manage, then a DI container would be the better choice.

Doc Brown
  • 199,015
  • 33
  • 367
  • 565
  • So BFactory in you answer is a sort of a builder class that will create D, C and B. Correct? – Erik Sapir Mar 26 '14 at 20:59
  • @ErikSapir: yes, I assumed you have already heard about the factory pattern. http://www.oodesign.com/factory-pattern.html – Doc Brown Mar 26 '14 at 21:10
  • Of course, i did. I just wondered if indeed it is common to use such factories to encapsulate the process of creating these dependencies – Erik Sapir Mar 26 '14 at 21:38
  • @ErikSapir: as I said, this depends on the intended life time and ownership. But for many scenarios its a feasible solution. – Doc Brown Mar 26 '14 at 21:57
1

If you're using a DI Container, the DI Container is responsible for figuring out what the needed dependencies are. If you're injecting dependencies through the class constructor, the caller of the constructor is responsible.

So in your original example of

A --> B --> C --> D

A would be responsible for handing the necessary dependencies to B, B would be responsible for handing the necessary dependencies to C, and so on.

Robert Harvey
  • 198,589
  • 55
  • 464
  • 673
  • In my example C received D as a dependency and B receives C as a dependency. So who constructs D? – Erik Sapir Mar 26 '14 at 20:22
  • *You do,* in whatever way that you would do that in C++ canonically (in C# or Java, it would be `new`). That first object creation is what triggers the creation chain. – Robert Harvey Mar 26 '14 at 20:24
  • Not sure what you mean. Lets assume that A is the entry point to the application. We want to create B. In order to create B, C should first be created and in order to create C, D should first be created. Should A be responsible to create D, C and B? Or are there better practices – Erik Sapir Mar 26 '14 at 20:28
  • Create a D, and hand it to the constructor of C. What happens after that is up to you... the remainder of the objects can create their own objects, or you can new up the entire chain yourself. The point of DI is not automatic instantiation of objects; it's about [inversion of control](http://programmers.stackexchange.com/q/205681/1204). – Robert Harvey Mar 26 '14 at 20:32
  • So what you are saying is that it is Ok if B will create C by itself? Isn't it a violation of DI? – Erik Sapir Mar 26 '14 at 20:38
  • 1
    I think you're getting a little hung up on automatic instantiation. The principle of inversion of control is that whoever is instantiating an object is responsible for handing that class whatever dependencies it needs through its constructor method. That's it; nothing else follows. – Robert Harvey Mar 26 '14 at 20:39