/cakephp-simple-di

Dependency Injection plugin for CakePHP

Primary LanguagePHP

SimpleDI plugin for CakePHP

Installation

You can install this plugin into your CakePHP application using composer.

The recommended way to install composer packages is:

composer require passchn/cakephp-simple-di

Load the plugin:

bin/cake plugin load Passchn/SimpleDI

Usage

In your Application.php:

public function services(ContainerInterface $container): void
{
    Configure::load('app_di');
    
    DIManager::create($container)
        // to add individual services: 
        ->addServices(Configure::readOrFail('DI.services'))
        /**
        * to collect multiple services, define a module: 
        * @see \Passchn\SimpleDI\Module\Module\ModuleInterface
        */
        ->addModules(Configure::readOrFail('DI.modules')) 
        /**
        * a plugin can define multiple modules: 
        * @see \Passchn\SimpleDI\Module\Plugin\PluginInterface
        */
        ->addPlugin(SomePlugin::class); 
}

Then, define Factories/Modules in your app_di.php:

return [
    'DI' => [
        'services' => [
            NewsletterService::class => NewsletterServiceFactory::class,
            CheckoutService::class => CheckoutServiceFactory::class,
            PaymentService::class => fn () => new PaymentService(),
        ],
        'modules' => [
            MyModule::class,
        ],
    ],
];

Factories should be Invokables or class-strings of Invokables.

You can then use the Service e.g. in Controller Actions:

class ExamplesController {
    
    public function someAction(NewsletterService $service): Response 
    {
        $service->doSomething();
    }
}

If real DI is not possible, e.g. in ViewCells, you can use the ServiceLocator to receive the container or Services.

Passchn\SimpleDI\Module\ServiceLocator\ServiceLocator::get(NewsletterService::class); // the service

This only works if you loaded the plugin or registered the container yourself, e.g.:

// in your Application::services()
ServiceLocator::setContainer($container);