mnavarrocarter / bolido
A minimal PSR-11 PHP DI Container powered by Reflection
Requires
- doctrine/annotations: ^1.6
- doctrine/inflector: ^1.3
- psr/container: ^1.0
This package is auto-updated.
Last update: 2019-08-18 18:30:08 UTC
README
A minimal reflection-powered DI Container for PHP.
I use this container for my personal projects. It's not quite ready for stable release yet. I would like to add some tests and try to find some bugs. If you want to help me with that, it would be awesome!
Install
composer require mnavarrocarter/bolido
Features
-
Service auto-injection: Using reflection, sniffs into the constructor and fetches the services declared in it, recursively.
-
Parameter auto-injection: When a dependency of a service is not a class, tries to guess the snake_case value of your camelCase variable name and looks it into the parameter bag to inject it.
-
Closure service register: You can also register serivices using closures or anonymous functions. The functions receive an instance of the container as a first argument.
-
Interface support: Using annotations you can specify a concrete implementation of an interface, right in the constructor of your service.
-
No config files required: Zero config files required. Simply just create a service class, define it's dependencies in the constructor, and just call it. Bolido will take care of everything.
Usage
To instantiate a new container, simply do:
<?php
use Bolido\Container;
$container = new Container();
Registering services is easy!
<?php
use Bolido\Container;
$container = new Container();
// Using closures
$container->set(SomeService::class, function($con) {
return new SomeService($con->getParameter('something'));
});
To fetch an instance of any class via the container, simply use the class constant for Bolido to find it. (Don't forget the use statement!). It will return a new instance if it doesn't have one on the container.
<?php
$service = $container->get(SomeService::class);
You can also store parameters, and fetch them:
<?php
use Bolido\Container;
$container = new Container();
$parameter = 'some-value';
$container->setParameter('parameter_name', $parameter);
$container->getParameter('parameter_name'); // 'some-value'
For registering third party services with complex config, simply create an adapter:
<?php
use Bolido\Container;
$container = new Container();
$container->setParameter('views_dir', '/resources/views');
class Twig extends \Twig_Environment
{
// Note that camelCase non type-hinted params are converted to snake_case,
// searched in the container and fetched it found.
public function __construct($viewsDir) {
$loader = new \Twig_Loader_Filesystem([$viewsDir]);
parent::__construct($loader);
}
}
$twig = $container->get(Twig::class);
$twig->render('some-html', ['data]);
A common problem of reflection containers is when declaring an interface in the
constructor. You can specify the concrete implementation you are using for this
interface with the @Resolve
annotation, specifying the short name of the
interface, and FQCN of the concrete implementation.
<?php
use Bolido\Annotation\Resolve;
use App\Service\SomeServiceInterface;
class SomeService
{
$private service;
/**
* @Resolve("SomeServiceInterface", concrete="App\Service\SomeConcreteService")
*/
public function __construct(SomeServiceInterfce $serviceName)
{
$this->service = $serviceName;
}
}
Container Injection
It is not recommended, but if you want to inject the full container into a service
or another class, simply make that class use the ContainerAwareTrait
. In the
instanciation process, Bolido will detect that trait and inject an instance of itself
into that class.