So, in order to use (constructor) DI you would have a constructor that looks like this:
public InvoiceController(InvoiceDao invoiceDao) {
this.invoiceDao = invoiceDao;
}
The key point to remember here is that this has been done so that in our unit tests we can inject a fake InvoiceDao. Now, let's say that our InvoiceDao class has one and only one constructor: public InvoiceDao() {
// sets up connection parameters, etc.
}
Then the constructor for InvoiceController could be simplified to: public InvoiceController() {
this.invoiceDao = new InvoiceDao();
}
This is quite a bit cleaner from an API perspective, and that is the entire point. This is only a simple example. For more complex classes, with multiple dependencies, it really becomes cumbersome. What if InvoiceController also needed access ReporterDao? Well, then you need to add that as a parameter to the constructor as well. Your API is made more complicated, all in an effort to make testing possible.This does not, of course, invalidate the benefits of unit testing, which are many. But it does expose a negative that is not frequently acknowledged, and that's what DHH is talking about, and what Kent has failed to address.