I'm a student of best practices, architectural patterns, and design principals. I have been studying dependency injection and inversion of control a lot lately, and have been "drinking the koolade" pretty extensively with a lot of my projects over the last half a year or so.
Recently, I got into a discussion about this with my boss. He asked me to expound the virtues of dependency injection particularly as it applies to our specific environment. He isn't a developer himself, but he has a keen ability to comprehend programming languages and related concepts. Specifically, he wanted me to explain to him why using dependency injection was better than having a core library which serves as an API. In other words, this is how we would traditionally architect an application, which has at its core an infrastructure module (data access):
and this is how it might look using DIP/DI
The arrows in each diagram of course represent the direction of dependency.
I told him that loosely-coupled code is always better because it allows you to swap components without affecting other areas of the application and having to re-write a lot of code to target the new components. I explained that coding to an abstraction rather than to a concrete API was preferable because it forces you to think in terms of that abstraction and thus elements specific to any concrete implementation are less-likely to leak out into other modules. I also explained that it's easier to test the components in isolation and use mocks for external systems.
Setting the testing argument aside for the moment, he wanted to know why we couldn't just modify the infrastructure module without affecting its public interface. For instance, if we decided to change from SQL Server to Oracle as a persistence technology, we could just make those changes in the data access module and the modules above it would be none the wiser.
I didn't have a good answer for him (other than the advantages for testing). Since we're unlikely to switch from SQL Server to Oracle in our particular environment, all I could go with was "it's just best practice" and reiterate the reasons I stated before.
What else could I have said to bolster my argument?
coding to an abstraction rather than to a concrete API was preferable because...What abstraction might you be referring to?