What is the "essence" of dependency injection? Is it the idea of dynamically swapping out/in core logical/structural aspects of a program at runtime?
Traditionally, this is done in code via some DI container. For example, using Structure Map in C#:
container.For<ICacheService>().Use<InMemoryCache>();
However, I've written several programs which inject code via configuration, in XML. Something like:
<cacheServiceProvider use="My.Namespace.InMemoryCache, MyAssembly"/>
That config is iterated at startup, and the various classes are instantiated for use throughout the program.
Is it fair to say that this is a form of DI? "Dependency Injection by Configuration"? Or does DI require configuration in code and the use of some container system?
Are their other philosophical or conventional aspects required to say something is "dependency injected," or am I completely misunderstanding this?