Use Controllers/Services/Models pattern and dependency injection

1 day ago 2
ARTICLE AD BOX

I'm building an API with Slim 4 and want to use the pattern Controllers/Services/Models, but I'm having some difficulties with dependency injection.

For the sake of example, I have these endpoints :

$app->get('/applyant/{id:[0-9]+}', function (Request $request, Response $response) { $user_model = new UserModel(); $internal = false; $user_service = new UserService($user_model, $internal); }); $app->get('/employee/{id:[0-9]+}', function (Request $request, Response $response) { $user_model = new UserModel(); $internal = true; $user_service = new UserService($user_model, $internal); });

I want to use controller in this way :

$app->get('/applyant/{id:[0-9]+}', UserController::class . ':getApplyant'); $app->get('/employee/{id:[0-9]+}', UserController::class . ':getEmployee');

I also have these classes :

class UserController { public UserService $user_service; public function __construct(UserService $user_service) { $this->user_service = $user_service; } public function getEmployee(ServerRequestInterface $request, ResponseInterface $response) { // Internal must be true here } public function getApplyant(ServerRequestInterface $request, ResponseInterface $response) { // Internal must be false here } } class UserService { public UserModel = $user_model; public string $internal; public function __construct(UserModel $user_model, bool $internal) { $this->user_model = $user_model; $this->internal = $internal; } } class UserModel { public int $id; public string $name; private \PDO $db; public function __construct(\PDO $db) { $this->pdo = $db; } }

All my classes must be covered by unit tests. Using dependency injection allow me to mock classes when I need it (e.g. PDO).
But I'm having trouble to use DI with the pattern above. I got the concept of auto-wiring (with PHP-DI for example), but for variable arguments such as $internal in UserService constructor, how am I supposed to manage it ?

I could use values array as mentionned in PHP-DI documentation (https://php-di.org/doc/php-definitions.html#values) :

return [ 'database.host' => 'localhost', 'database.port' => 5000, 'report.recipients' => [ '[email protected]', '[email protected]', ], ];

But the value is known only in the controller.
Am I missing something or am I totally wrong in my implementation of my classes with DI ?

Read Entire Article