in Concepts, Uncategorized

Dependency Injection and IOC Containers

Dependency injection

Dependency injection and IOC are patterns that have been talked about a lot.
If you are using something like spring(java) or Laravel(PHP) you might be using DI and IOC without even knowing it.

But what exactly are they and why should you care?

I’ll take an example of the obligatory order processing system to make things concrete.

class OrderSystem {
    ...
    function processOrder($order) {
        orderProcessor = new SimpleOrderProcessor()
        if ($order.validate()) {
            orderProcessor.process($order);
            return true;
        }
        return false;
    }
    ...
}

What do you think is the problem with the method?

  • Tight Coupling – The OrderSystem is tightly coupled to the SimpleOrderProcessor, if somebody else wanted to use this code with a different OrderProcessor they would have to make some modification.
  • Testing – If we want to unit test this function how do we mock the OrderProcessor?

Lets see if we can do something better.

class OrderSystem {
    protected $orderProcessor;
    public __construct($orderProcessor) {
        $this->orderProcessor = $orderProcessor;
    }
 ...
     function processOrder($order) {
         if ($order.validate()) {
             $this->orderProcessor.process($order);
             return true;
         }
         return false;
     }
 ...
}

With a small modification we have made our code more testable. Now we can easily mock the orderProcessor by passing a dummy object while creating OrderSystem.

Voila! you have done a dependency injection. This is also called constructor injection (1IOC).

There are different ways of doing dependency injection.

  • Constructor injection (we just did this!)
  • Setter Injection
  • Interface Injection

DI is not the only way of decreasing coupling, another pattern used a lot is Service Locator but i’ll talk about it some time else.

Setter injection

Instead of passing dependency in constructor we can use a setter method to set the dependency.

class OrderSystem {
     protected $orderProcessor;
     public function setOrderProcessor($orderProcessor) {
        $this->orderProcessor = $orderProcessor;
     }
     ...
}

How is this different from constructor injection you say!

  • Partial Injection – With constructor you cannot instantiate the object without passing all dependency if you have such use case setter injection would be the way to go.
  • Overriding Injection – You can override dependencies at runtime again not possible through constructor injection.

Interface Injection

This is a little more verbose but bear with me.

public interface InjectOrderProcessor {
    void injectOrderProcessor(ObjectProcessor objectProcessor);
}
 
public class OrderSystem implements OrderProcessorInject {
    ...
    void injectOrderProcessor(ObjectProcessor objectProcessor) {
        this.objectProcessor = objectProcessor;
    }
    ...
}
 
public class OrderProcessor implements Injector {
    public void inject(Object target) {
        ((InjectOrderProcessor) target).injectOrderProcessor(this);        
    }
}

With this kind of structure we can inject the orderProcessor by instantiating it and then passing the dependant object to it.

Seems like too much effort, wait there is something out there that can help IOC Containers.

IOC Containers

Ioc container are convenience constructs that can help remove all the boiler plate/extra work of wiring up the dependencies.

It may seem small in the above example but as hierarchy increases the savings in manual creation of objects can be substantial.

Configuration can be provided to containers as code or xml files depending on the choice of  container.
Some popular ones for java are spring, PICO container, guice(highly recommended for non-spring projects)if you are coming from php pimple might be a good option.

Please leave feedback by commenting below. If you liked the post share and follow.

Write a Comment

Comment