tobento / service-container
A PSR-11 container with autowiring.
Requires
- php: >=8.0
- psr/container: ^2.0
- tobento/service-autowire: ^1.0
Requires (Dev)
- phpunit/phpunit: ^9.5
- vimeo/psalm: ^4.0
README
The Container Service provides a PSR-11 container with autowiring.
Table of Contents
Getting started
Add the latest version of the container service running this command.
composer require tobento/service-container
Requirements
- PHP 8.0 or greater
Highlights
- Framework-agnostic, will work with any project
- Decoupled design
- Autowiring
Documentation
PSR-11
use Tobento\Service\Container\Container; $container = new Container(); $has = $container->has(Foo::class); $foo = $container->get(Foo::class);
Autowiring
The container resolves any dependencies by autowiring, except build-in parameters needs a definition to be resolved.
On union types parameter, the first resolvable parameter gets used if not set by definiton.
Definitions
By providing the resolved object:
use Tobento\Service\Container\Container; class Foo { public function __construct( private string $name ) {} } $container = new Container(); $container->set(Foo::class, new Foo('value')); $foo = $container->get(Foo::class);
By defining the missing parameters:
use Tobento\Service\Container\Container; class Foo { public function __construct( private string $name ) {} } $container = new Container(); // By the construct method: $container->set(Foo::class)->construct('value'); // By the with method using parameter name: $container->set(Foo::class)->with(['name' => 'value']); // By the with method using parameter position: $container->set(Foo::class)->with([0 => 'value']); $foo = $container->get(Foo::class);
By using a closure:
The container will automatically resolve any closure arguments.
use Tobento\Service\Container\Container; class Foo { public function __construct( private string $name ) {} } class Bar { public function value(): string { return 'value'; } } $container = new Container(); $container->set(Foo::class, static function(Bar $bar) { return new Foo($bar->value()); }); $foo = $container->get(Foo::class);
You might configure which implementation to use:
$container->set(BarInterface::class, Bar::class);
Defining method calls: You will need only to define build-in parameters as others get autowired if you want to.
use Tobento\Service\Container\Container; class Foo { public function index(Bar $bar, string $name) {} } class Bar {} $container = new Container(); $container->set(Foo::class)->callMethod('index', ['name' => 'value']); $container->set(Foo::class)->callMethod('index', [1 => 'value']); $foo = $container->get(Foo::class);
Prototype Definition:
You might declare the defintion as prototype, meaning returning always a new instance.
use Tobento\Service\Container\Container; class Foo {} class Bar {} $container = new Container(); $container->set(Foo::class)->prototype(); $container->set(Bar::class, function() { return new Bar(); })->prototype(); var_dump($container->get(Foo::class) === $container->get(Foo::class)); // bool(false) var_dump($container->get(Bar::class) === $container->get(Bar::class)); // bool(false)
Make
The make() method works like get() except it will resolve the entry every time it is called.
use Tobento\Service\Container\Container; class Foo { public function __construct( private Bar $bar, private string $name ) {} } class Bar {} $container = new Container(); $foo = $container->make(Foo::class, ['name' => 'value']);
Call
For more detail visit: service-autowire#call
class Foo { public function index(Bar $bar, string $name): string { return $name; } } class Bar {} $container = new Container(); $name = $container->call([Foo::class, 'index'], ['name' => 'value']);
Resolver
You might adjust your requirements by adding a custom resolver which implements the following interface:
use Tobento\Service\Container\Container; use Tobento\Service\Container\ResolverInterface; $container = new Container(new CustomResolver());
/** * ResolverInterface */ interface ResolverInterface { /** * Resolve the given identifier to a value. * * @param string $id Identifier of the entry. * @param array<int|string, mixed> $parameters * * @return mixed */ public function resolve(string $id, array $parameters = []): mixed; /** * Resolve the given definition. * * @param DefinitionInterface $definition * * @return mixed The value of the resolved definition. */ public function resolveDefinition(DefinitionInterface $definition): mixed; /** * If the given identifier is resolvable. * * @param mixed $id Identifier of the entry. * @return bool True if resolvable, otherwise false. */ public function isResolvable(mixed $id): bool; }