I’m migrating my code from v3 to v4.
I’ve setup a new DI\Container in my code.
And use the class name as the key as it’s suggested :
/**
* 'clientInputValidator' (old name)
*/
ClientInputValidator::class => function (ContainerInterface $c)
{
return new ClientInputValidator($c->get(LoggerInterface::class));
},
and thus, I need to update my code from
$inputValidator = $this->clientInputValidator
to $inputValidator = $this->get(ClientInputValidator::class)
but this add the need to add in my php files use \RedCrossQuest\Service\ClientInputValidator;
everywhere i need to use the service, while I don’t see the added value and which makes a bit harder the conversion to v4
I don’t have completion, can’t set a type to inputValidator.
I don’t see the advantage of using this way of naming the services in my container.
Also, I can’t have two instance of a same class/interface in my container with this method. (since the class/interface is the key and both have the same class/interface)
I need to update my code from
$inputValidator = $this->clientInputValidator
to $inputValidator = $this->get(ClientInputValidator::class)
This is not true, it’s the opposite. Please don’t refactor “back” to the service locator anti-pattern.
Instead declare all class dependencies in the constructor and let the dependency injection container inject it for you: Autowiring
And you even don’t need to add definitions for ALL services classes. You can remove this definition if you make use of constructor injection: ClientInputValidator::class => function (ContainerInterface $c)
Pseudo example:
final class ClientInputValidator
{
private $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
public function validate(array $data): ValidationResult
{
// ...
}
}
but my routes are just callback functions with no constructor.
Closures (functions) as routing handlers are quite “expensive” because PHP has to create all closures for each request. The use of class names is more lightweight, faster and scales better for larger applications.
And it looks like it’s the correct way to go, thanks for the hint.
Any hint on how to specify my settings array to the constructor of my class ?
I would recommend using constructor injection to inject the configuration. You could use a generic or a class specific Configuration class for this purpose.
* @Inject("settings")
This looks like “black magic” to me (and the IDE and phpstan)