Reconfiguration is overrated. The most important thing you get from using DI is testability. Since your classes don't depend on implementations but on abstractions you can replace them with mocks / stubs in your unit tests.
Example
Without DI:
class SaleAction{
private BillingService billingService;
public SaleAction(){
billingService = new CreditCardService(); //dependency is hardcoded
}
public void pay(long amount){
//pre payment logic
billingService.pay(amount);
//post payment logic
}
}
In that example suppose you want to unit test the pre-payment logic and post-payment logic of SaleAction
... you can't because SaleAction
is coupled to CreditCardService
and probably running your tests will generate fake payments.
Now the same example with DI:
class SaleAction{
private BillingService billingService;
public SaleAction(BillingService service){
billingService = service; //DI
}
public void pay(long amount){
//pre payment logic
billingService.pay(amount);
//post payment logic
}
}
Now SaleAction
is decoupled from any implementation, which means that in your test you can do SaleAction action = new SaleAction(new DummyBillingService());
.
Hope that helps, there's also the article about DI, written by Martin Fowler that you can find here