My questions are specifically dealing with dependency injection through the constructor. I understand the pros/cons of service locator pattern, constructor/setter injection, and their flavors, however there is something I can't seem to get past after choosing pure constructor injection. After reading many materials for testable design, including a thorough perusing of Miško Hevery's blog (specifically this post) I'm at the following situation:
Assume I'm writing a C++ program, and I have correctly injected my dependencies through their constructors. For readability I have given myself a high-level object which has a single Execute() function called from main:
int main(int argc, char* argv[]) {
MyAwesomeProgramObject object(argc, argv);
return object.Execute();
}
Execute()'s responsibility is to simply wire up all required objects and kick off the highest level object. The highest level object requires a couple dependencies and those objects required a few objects and so on and so on, implying a function that looks like this:
MyAwesomeProgramObject::Execute() {
DependencyOne one;
DependencyTwo two;
DependencyThree three;
MidLevelOne mid_one(one);
MidLevelTwo mid_two(two, three);
// ...
MidLevelN mid_n(mid_dependencyI, mid_dependencyJ, mid_dependencyK);
// ...
HighLevelObject1 high_one(mid_one, mid_n);
HighLevelObject2 high_two(mid_two);
ProgramObject object(high_one, high_two);
return object.Go();
}
From what I take from Miško's blog (and I would ask him, but figured he wouldn't have time to get back to me), this is the only way to satisfy pure constructor injection of dependencies.
In the blog post mentioned, he states we should have factories on a per object lifetime level, but this is essentially what Execute is doing, making my code look identical to his example:
AuditRecord audit = new AuditRecord();
Database database = new Database(audit);
Captcha captcha = new Captcha();
Authenticator authenticator =
new Authenticator(database, captcha, audit);
LoginPage = new LoginPage(audit, authenticator);
Questions:
- Is this the standard approach?
- Is this a pattern that I'm not aware of (seems similar to Maven's context.xml)?
- For pure constructor injection, do I simply suffer the cost of "upfront" allocation?