Injection dependence Fine structure 3

I am using Slim Framework 3 to create an API. Application structure: MVCP (model, view, controller, suppliers).

Is it possible to have a Slim Dependency Inject for all my classes?

I use composer to autoload all my dependencies.

My directory structure looks like this:

/app - controllers/ - Models/ - services/ index.php /vendor composer.json 

Here is my composer.json file.

 { "require": { "slim/slim": "^3.3", "monolog/monolog": "^1.19" }, "autoload" : { "psr-4" : { "Controllers\\" : "app/controllers/", "Services\\" : "app/services/", "Models\\" : "app/models/" } } } 

Here is my index.php file. Again, dependencies are automatically entered by the composer

 <?php use \Psr\Http\Message\ServerRequestInterface as Request; use \Psr\Http\Message\ResponseInterface as Response; require '../vendor/autoload.php'; $container = new \Slim\Container; $app = new \Slim\App($container); $app->get('/test/{name}', '\Controllers\PeopleController:getEveryone'); $app->run(); 

My controller is as follows

 <?php #controllers/PeopleController.php namespace Controllers; use \Psr\Http\Message\ServerRequestInterface as Request; use \Psr\Http\Message\ResponseInterface as Response; class PeopleController { protected $peopleService; protected $ci; protected $request; protected $response; public function __construct(Container $ci, PeopleService $peopleService) { $this->peopleService = $peopleService; $this->ci = $ci; } public function getEveryone($request, $response) { die($request->getAttribute('name')); return $this->peopleService->getAllPeoples(); } } 

My PeopleService file looks like this:

 <?php namespace Services; use Model\PeopleModel; use Model\AddressModel; use Model\AutoModel; class PeopleService { protected $peopleModel; protected $autoModel; protected $addressModel; public function __construct(PeopleModel $peopleModel, AddressModel $addressModel, AutoModel $autoModel) { $this->addressModel = $addressModel; $this->autoModel = $autoModel; $this->peopleModel = $peopleModel; } public function getAllPeopleInfo() { $address = $this->addressModel->getAddress(); $auto = $this->autoModel->getAutoMake(); $person = $this->peopleModel->getPeople(); return [ $person[1], $address[1], $auto[1] ]; } } 

Models/AddressModels.php

 <?php namespace Model; class AddressModel { public function __construct() { // do stuff } public function getAddress() { return [ 1 => '123 Maple Street', ]; } } 

Models/AutoModel.php

 namespace Model; class AutoModel { public function __construct() { // do stuff } public function getAutoMake() { return [ 1 => 'Honda' ]; } } 

Models/PeopleModel.php

 <?php namespace Model; class PeopleModel { public function __construct() { // do stuff } public function getPeople() { return [ 1 => 'Bob' ]; } } 

ERROR Now I get the following error:

 PHP Catchable fatal error: Argument 2 passed to Controllers\PeopleController::__construct() must be an instance of Services\PeopleService, none given, called in /var/www/vendor/slim/slim/Slim/CallableResolver.php on line 64 and defined in /var/www/app/controllers/PeopleController.php on line 21 

QUESTION How can I use all my classes? Is there a way to automatically tell Slim DI Container to do this?

+5
source share
1 answer

When you refer to a class in a route called by Slim, it will ask for a DIC for it. If the DIC has no registration for this class name, it will instantiate the class itself, passing the container as the only argument to the class.

Therefore, to enter the correct dependencies for your controller, you just need to create your own DIC factory:

 $container = $app->getContainer(); $container['\Controllers\PeopleController'] = function ($c) { $peopleService = $c->get('\Services\PeopleService'); return new Controllers\PeopleController($c, $peopleService); }; 

Of course, now you need a DIC factory for PeopleService:

 $container['\Services\PeopleService'] = function ($c) { $peopleModel = new Models\PeopleModel; $addressModel = new Models\AddressModel; $autoModel = new Models\AutoModel; return new Services\PeopleService($peopleModel, $addressModel, $autoModel); }; 

(If PeopleModel, AddressModel, or AutoModel had dependencies, then you would create DIC factories too.)

+4
source

Source: https://habr.com/ru/post/1247889/


All Articles