-
-
Notifications
You must be signed in to change notification settings - Fork 0
Registering an instance
$container->set(string $id, $entry): static| Parameters | Type | Description |
|---|---|---|
$id |
string |
Name of the service |
$entry |
callable, object
|
Instance of the service |
There's few ways to register your services to the container as follow:
1. Use callable string or array
// callable string of a function name
$container->set('id', 'functionName');
// callable string of a class::method pair
$container->set('id', 'ClassName::methodName');
// callable array as an object of class and method pair
$container->set('id', [$classInstance, 'methodName']);
// callable array as a string of class name and method pair
$container->set('id', [ClassName::class, 'methodName']);By passing 2nd argument as a class-method pair (whether it's a string or array) it would work regardless the method is a static or not. Let say we have the following
class SomeClass implements CertainInterface
{
public static function staticMethod() {
// some codes
}
public function nonStaticMethod() {
// some codes
}
}
$container->set(CertainInterface::class, 'SomeClass::staticMethod'); // OR
$container->set(CertainInterface::class, 'SomeClass::nonStaticMethod'); // OR
$container->set(CertainInterface::class, [SomeClass::class, 'staticMethod']); // OR
$container->set(CertainInterface::class, [SomeClass::class, 'nonStaticMethod']); // OR
$container->set(CertainInterface::class, [new SomeClass, 'staticMethod']); // OR
$container->set(CertainInterface::class, [new SomeClass, 'nonStaticMethod']);// Instance of class
$container->set('myService', new SomeClass);
// String of class name
$container->set('myService', SomeFactoryClass::class);You can use name of the registered service as the $entry parameter.
// Based on example above
$container->set(CertainInterface::class, function () {
return new SomeClass;
});
$container->set(AnotherInterface::class, CertainInterface::class);
$container->set('someClass', CertainInterface::class);
// So you could access instance of SomeClass with the following
$container->get(CertainInterface::class); // OR
$container->get(AnotherInterface::class); // OR
$container->get('someClass');That said, we also have the option to register a method from existing container as follow
class SomeClass implements CertainInterface
{
public function theMethod() {
return 'a value';
}
}
$container->set(CertainInterface::class, SomeClass::class);
$container->set('foo', function (CertainInterface $bar) {
return $bar;
});
// Because the container 'foo' is technically returns the instance of CertainInterface
$container->set('bar', 'foo::theMethod'); // => returns 'a value'
// Because the CertainInterface is registered as a container
$container->set('baz', [CertainInterface::class, 'theMethod']); // => returns 'a value'- By registering an entry this way, the container will check whether it's a callable class or not.
- If it's a callable class, then the
Container::get()method will returns any returns value from the__invoke()method instead of the instance of the class.
Let say you have the following class
class FooBar {
protected $foo
public function __construct(Foo $foo) {
$this->foo = $foo;
}
/**
* The __invoke method returns void.
*/
public function __invoke(Bar $bar): void {
$this->foo->setBar($bar);
}
}
$container->set(FooBar::class, FooBar::class);
// What you'll get
$container->get(FooBar::class); // => returns voidThat said, it's possible to have an entry that returns unexpected value, this will led you to an error when you trying to register a new entry and require the invalid entry as dependency.
$container->set('foo', function (FooBar $foobar) {
// the codes.
});When the container trying to resolve foo entry, it will fetch FooBar entry and inject it to the callback, so you'll got TypeError thrown.
So its recommended to always use Closure as an entry factory and injecting the required dependencies from its arguments.
$container->set('foobar', function (Foo $foo, Bar $bar) {
return new FooBar($foo, $bar);
});