DEV Community

Cojiroooo
Cojiroooo

Posted on

DI Container on CakePHP4.3 upper

Motivation

I want to inject Service to Command and Controller by DI container.
In addition, Service uses Repository injected.
The document doesn't mention this case like nested injection.

Document

https://book.cakephp.org/4/en/development/dependency-injection.html

How to implement

Service and Repository

interface SomeRepository { public getAll(): array; } 
Enter fullscreen mode Exit fullscreen mode
class SomeRepositoryImpl implements SomeRepository { public function getAll(): array { print('getAll()'); return []; } } 
Enter fullscreen mode Exit fullscreen mode
class SomeService { private $someRepository; public function __construct(SomeRepository $someRepository) { $this->someRepository = $someRepository; } public function doSomething(): void { $this->someRepository->getAll(); } } 
Enter fullscreen mode Exit fullscreen mode

Comamnd

use Cake\Command\Command; use Cake\Console\Arguments; use Cake\Console\ConsoleIo; use Cake\Console\ConsoleOptionParser; class SomeCommand extends Command { private SomeService $service; public function __construct(SomeService $service) { parent::__construct(); $this->service = $service; } public static function getDescription(): string { return 'Inject service through provider'; } public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser { $parser = parent::buildOptionParser($parser); return $parser; } public function execute(Arguments $args, ConsoleIo $io) { $this->service->doSomething(); } } 
Enter fullscreen mode Exit fullscreen mode
use Cake\Core\ContainerInterface; use Cake\Core\ServiceProvider; class CommandServiceProvider extends ServiceProvider { protected $provides = [ SomeCommand::class, ]; public function services(ContainerInterface $container): void { $container ->add(SomeCommand::class) ->addArgument(SomeService::class); } } 
Enter fullscreen mode Exit fullscreen mode

Controller

use Cake\Controller\Controller; class SomeController extends Controller { public function index(SomeService $service) { $service->doSomething(); print('index()'); } } 
Enter fullscreen mode Exit fullscreen mode

Register to DI container

use Cake\Core\ContainerInterface; use Cake\Core\ServiceProvider; class SomeServiceProvider extends ServiceProvider { protected $provides = [ SomeService::class, ]; public function services(ContainerInterface $container): void { $container ->add(SomeRepository::class, SomeRepositoryImpl::class); $container ->add(SomeService::class) ->addArgument(SomeRepository::class); } } 
Enter fullscreen mode Exit fullscreen mode
// Application.php class Application extends BaseApplication { // ... public function services(ContainerInterface $container): void { $container->addServiceProvider(new SomeServiceProvider()); $container->addServiceProvider(new ControllerServiceProvider()); } // ... 
Enter fullscreen mode Exit fullscreen mode

Top comments (0)