What are Dependency Injection & Spring Framework about?

Spring has turned into a huge framework, which may be confusing you if you are only trying to wrap your head around dependency injection. The Google Guice project is tiny and only does DI with pure Java--no XML and no extras. There's a nice introductory video explaining DI too. http://code.google.com/p/google-guice/


We use Dependency Injection (DI) to implement loose coupling. The choice of any particulary DI Container is not that important.

Every time you create an instance of a class by using the new keyword, you tightly couple your code to that class, and you will not be able to substitute that particularl implementation with a different one (at least not without recompiling the code).

This would look something like this in C# (but would be equivalent in Java):

public class MyClass
{
    public string GetMessage(int key)
    {
        return new MessageService().GetMessage(key)
    }
}

This means that if you would later like to use a different MessageService, you can't.

On the other hand, if you inject an interface into the class and adhere to the Liskov Substition Principle, you will be able to vary the consumer and the service independently.

public class MyClass
{
    private readonly IMessageService messageService;

    public MyClass(IMessageService messageService)
    {
        if(messageService == null)
        {
            throw new ArgumentNullException("messageService");
        }

        this.messageService = messageService;
    }

    public string GetMessage(int key)
    {
        return this.messageService.GetMessage(key)
    }
}

Although this looks more complicated, we have now managed to follow the Single Responsibility Principle by ensuring that each collaborator does only one thing, and that we can vary both independently of each other.

Furthermore, we can now change MyClass' behavior without changing the class itself, thus adhering to the Open/Closed Principle.


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


Here's a good article explaining the ideas of spring. (By Rod Johnson, the founder of the Spring framework)