Revision: Sat, 01 Aug 2020 19:23:52 GMT

Cookbook - Injectors

You can control the creation process of any interface or abstract class children using an injection interface. This article demonstrates how to create a class instance and assign a unique value to it, no matter what children implement it.

abstract class Model
{
    public $id;
    public $context;
}

We can combine bootloader and injector into one instance:

namespace App\Bootloader;

use App\Model;
use Spiral\Boot\Bootloader\Bootloader;
use Spiral\Core\Container;

class ModelBootloader extends Bootloader implements Container\InjectorInterface, Container\SingletonInterface
{
    private $id = 0;

    public function boot(Container $container)
    {
        $container->bindInjector(Model::class, self::class);
    }

    public function createInjection(\ReflectionClass $class, string $context = null)
    {
        $model = $class->newInstance();
        $model->context = $context;
        $model->id = $this->id++;

        return $model;
    }
}

Do not forget to activate the bootloader.

Multiple children are allowed:

namespace App;

class A extends Model
{

}

and

namespace App;

class B extends Model
{

}

Now, any model request will include unique id, for example in the controller method:

namespace App\Controller;

use App\A;
use App\B;

class HomeController
{
    public function index(A $first, B $second)
    {
        assert($first->id > $second->id);

        assert($first->context === 'first');
        assert($first->context === 'second');
    }
}

You can call make and get methods inside the injectors... but instead use the force.

Edit this page