Transparent dependency injection in controller


Nov '16

Oct '17

2

308

1

edited Nov '16
Nov '16
<?php

trait InjectableTrait
{
    protected function injectDependencies()
    {
        if (!method_exists($this, 'inject')) {
            return;
        }

        $reflectionMethod = new \ReflectionMethod($this, 'inject');
        $methodParams = $reflectionMethod->getParameters();

        $params = [];

        if (!count($methodParams)) {
            return;
        }

        if ($this instanceof \Phalcon\Di\Injectable) {
            $di = $this->getDI();
        } else {
            $di = \Phalcon\Di::getDefault();
        }

        foreach ($methodParams as $key => $methodParam) {
            if ($methodParam->getClass()) {
                $className = $methodParam->getClass()->getName();
                if ($di->has($className)) {
                    $params[$key] = $di->getShared($className);
                } elseif (class_exists($className)) {
                    $params[$key] = new $className();
                }
            } elseif ($di->has($methodParam->getName())) {
                $params[$key] = $di->getShared($methodParam->getName());
            } else {
                $params[$key] = null;
            }
        }

        call_user_func_array([$this, 'inject'], $params);
    }
}

abstract class BaseController extends \Phalcon\Mvc\Controller
{
    use InjectableTrait;

    public function onConstruct()
    {
        $this->injectDependencies();
    }
}

class UsersController extends BaseController
{
    protected $stdClass;
    protected $filter;
    protected $modelsManager;

    public function inject($filter, $modelsManager, \stdClass $stdClass)
    {
        $this->filter = $filter;
        $this->modelsManager = $modelsManager;
        $this->stdClass = $stdClass;
    }

    public function indexAction()
    {
        $this->filter-> ...
        $this->modelsManager-> ...
        $this->stdClass-> ...
    }
}

Thien
33.8k

Look nice :)