Most of my production code has fixed types of dependencies, illustrated below: the House for example, at run time, always depends on the same Kitchen.
Therefore, I am wondering what I gain by having the House force whoever constructs it to inject its dependencies as opposed to provide the option to inject the dependencies, i.e. provide both a default constructor and a DI-constructor?
What you lose by not allowing default construction is easily seen if you compare mainDI and mainDefault.
Even if each class has only has two dependencies, if the dependency hierarchy depth is 3, as for example in the House -> Bedroom -> Bed path, you have to instantiate 2^3 objects in your top level class which seems unfeasible for large projects with a dependency hierarchy depth of 10 or more.
Having the DI constructor, I am still able to unit test a class.
So for all the DI experts out there, what is the downside of this approach?
struct House {
House(Bedroom ib, Kitchen ik) : b(ib), k(ik) {}
House() : b(Bedroom()), k(Kitchen()) {}
private:
Bedroom b;
Kitchen k;
}
struct Bedroom {
Bedroom(Bed ib, Lamp il) : b(ib), l(il) {}
Bedroom() : b(Bed()), l(Lamp()) {}
private:
Bed b;
Lamp l;
}
struct Bed {
Bed(Frame if, Mattress im) : f(if), m(im) {}
Bed() : f(Frame()), m(Mattress()) {}
private:
Frame f;
Mattress m;
}
mainDefault() {
House h()
}
mainDI() {
Frame f;
Mattress m;
Bed b;
Lamp l;
Kitchen k;
Bed b(f, m);
Bedroom br(b, l);
House h(br, k);
}