Dependency Injection

Improvements?

Let us know by posting here.

Dependency Injection Explained

Dependency Injection (DI) simplifies class dependencies management. It involves providing dependencies through a class constructor, enhancing code quality and testability. Consider this class example:

<?php

namespace Application\MarinaPortal\Boat;

class BoatLister
{
    public function __construct(DatabaseConnection $db)
    {
        $this->db = $db;
    }

    public function getBoats()
    {
        $r = $this->db->executeQuery('select * from Boats');
    }

    public function getBoatByID($id)
    {
        $r = $this->db->executeQuery('select * from Boats where id = ?', [$id]);
    }
}

Use the class as $list = new BoatLister(\Database::getConnection());. DI centralizes dependency management, making classes cleaner and more testable.

Automated Dependency Injection with Containers

Concrete's container automates object creation and dependency management:

$list = $this->app->make(BoatLister::class);
// or
$list = Core::make(BoatLister::class);

To use specific dependencies or mockups:

$this->app->make(BoatLister::class, ['db' => $mockupInstance]);

Container Mechanics

The container, by default, automatically instantiates dependency classes using PHP's Reflection. Custom behaviors include:

  • Singletons (reuse instance):

    $this->app->singleton('Concrete\Core\Database\DatabaseManager');
    
  • Interface Bindings (interface to class):

    $this->app->bind('Concrete\Core\Database\EntityManagerConfigFactoryInterface', 'Concrete\Core\Database\EntityManagerConfigFactory');
    
  • Custom Instance Creation:

    $this->app->bind(PersonResolver::class, function(Application $app) {
      return YourWayToCreateThePersonResolverInstance;
    });
    

Further Reading