theredlabs/mikado-di

The simplest yet very flexible Dependency Injection Container


License
MIT

Documentation

Mikado Dependency Injection Container

1. Description

This project provides a set of classes that allows the creation of a dependency container that can be configured to store diferent objects and their relationship to each other.

It's a very simple yet flexible IoC DI container.

2. Installation

2.1 Composer

Installation is as simple as:

composer install theredlabs/mikado-di

3 Usage

3.1 Quick and Dirty Example

<?php
use theredlabs\di\Container;

interface iGeolocationService
{
    public function getCoordinates(string $location);
}

class OpenStreetService implements iGeolocationService
{
    public function getCoordinates(string $location)
    {
        return "(0,0)";
    }
}

class GoogleMapsService implements iGeolocationService
{
    /**
     * @var string
     */
    protected $apiKey;

    function __construct(string $apiKey)
    {
        $this->apiKey = $apiKey;
    }

    public function getCoordinates(string $location)
    {
        return "(1,1)";
    }
}

class Geolocator
{
    /**
     * @var iGeolocationService
     */
    protected $service;

    function __construct(iGeolocationService $service)
    {
        $this->service = $service;
    }

    public function getCoordinates($location)
    {
        return $this->service->getCoordinates($location);
    }
}

$container = Container::getInstance();
$container->register('geolocator', 'Geolocator');

// You have to select the service you want to use:
$container->getConfig('geolocator')->dependency('GoogleMapsService', array('apiKey' => '123123123123'));
// $container->getConfig('geolocator')->parameter('service', new OpenStreetService());

echo $container->geolocator->getCoordinates('Home'); // (0,0) or (1,1)

Theory of Operation

There are several different approaches in order to implement the Inversion of Control (IoC) pattern via Dependency Injection:

  • Constructor Injection
  • Parameter Injection
  • Setter Injection
  • Interface Injection

This container uses the Constructor Injection approach, where each class defines it's dependencies and its types in the constructor declaration.

Internally, the container has an object store which is basically an associative array that maps a key to your object/class. Once you have defined the "target" class/object, you get the configuration for it and then assign a dependency that can be either an object, a fully qualified classname including it's name space (more on this later) or and object store key.

Optionally you can also set constructor parameters by it's name, e.g. you need to pass and API key to a class or to any of it's dependencies.