inversion of control

A very handy pattern for large projects. Think of it as an enhancement from the dependency injection pattern.

When using dependency injection, the caller of a class provides the implementations of the requirements.
This gets cumbersome with classes which have a lot of requirements, and large code bases where you may not even know where the implementation is, or how it is called.

Inversion Of Control to the rescue: With this pattern, the framework provides the implementations.

As the implementation is a bit more complex, I’ll only explain the concept:

  • Create a helper, which can construct classes with requirements (non-empty contructor with interfaces)
  • Register the implementations you want to use against the helper at a central place in your code
  • Retrieve all classes which have requirements over this helper

An Example in pseudo-php code:

class IoCContainer extends Singleton
{
    private $registeredInterfaces = array();
    public function register($interface, $implementation)
    {
        $this->registeredInterfaces[$interface] = $implementation;
    }

    public function construct($object)
    {
        $arguments = get_needed_arguments($object);
        //match each argument with an implementation, and construct the object
        return $instance;
    }
}

now at the start of your application you register the implementations:

IoCContainer::getInstance()->register("IProgress",new ProgressService());
class Workflow
{
    public function __construct(IProgress $progressService) { }

    public function doStuff() { }
}
IoCContainer::getInstance()->construct("Workflow")->doStuff();

Now, you do not want to write an IoCContainer yourself. Not because it is hard, but because it has been made before, and tested before. For C# I can recommend the SimpleIoC Container from the MVVMLight Package: MVVM Light (you can get it over NuGet). There are similar implementations for most other languages.

dependecy injection

This is one of my favorite patterns out there! Use this if you have a large codebase or multiple consumers of a library.

Use case: You have some code, and multiple Consumers (Webpage, Phone Application & Desktop Application) which want to use the contained Logic (so you do not copy paste the same code three times). Now you want to show progress for a long running operation in the DownloadLargeFileWorkflow. What to do:

  • You create a IProgress interface
  • Each of your Consumers implements this interface
  • You pass the instance which implements this interface to the shared code.

Ready! Now you can use the same code for all three very different consumers.

Now how to implement this?

public interface IProgress
{
    void ShowProgress();
    void HideProgress();
}

public class DownloadLargeFileWorkflow
{
    private IProgress _progress;
    pulic DownloadLargeFileWorkflow(IProgress progress)
    {
        _progress = progress;
    }

    public void Execute()
    {
        _progress.ShowProgress();
        //do long running operation
        _progress.HideProgress();
    }
}

In your consumer specific code you can now construct the DownloadLargeFileWorkflow with your specific implementation of the IProgress interface.