2017 © Pedro Peláez
 

cakephp-plugin piping-bag

CakePHP 3 plugin for using Ray.Di as a Dependency Injection Container

image

lorenzo/piping-bag

CakePHP 3 plugin for using Ray.Di as a Dependency Injection Container

  • Tuesday, May 23, 2017
  • by lorenzo
  • Repository
  • 4 Watchers
  • 33 Stars
  • 9,818 Installations
  • PHP
  • 1 Dependents
  • 1 Suggesters
  • 7 Forks
  • 0 Open issues
  • 5 Versions
  • 18 % Grown

The README.md

Dependency Injection Container Plugin for CakePHP 4

This plugin adds the ability to configure object instances and their dependencies before they are used, and to store them into a container class to easy access., (*1)

It uses the clean and flexible Ray.Di Library which is a PHP dependency injection framework in the style of "Google Guice"., (*2)

Ray.Di also allows you to program using AOP, that is, decorating the configured instances so some logic can be run before or after any of their methods., (*3)

Installation

You can install this plugin into your CakePHP application using composer., (*4)

composer require lorenzo/piping-bag=dev-master

Configuration

Upgrading from library version 1.x (Cake 3.x)

DEPRECATED: - ControllerFactoryFilter.php for injecting controllers - ShellDispatcher.php for injecting shell classes, (*5)

Remove the following lines in your: config/bootstrap.php:, (*6)

DispatcherFactory::add('PipingBag\Routing\Filter\ControllerFactoryFilter');
Plugin::load('PipingBag', ['bootstrap' => true]);

Controller Injection

For getting injection in your controllers to work you need to add the following line in the bootstrap method of your Application.php:, (*7)

$this->addPlugin('PipingBag', ['bootstrap' => true]);
$this->controllerFactory = new \PipingBag\Controller\DIControllerFactory();

Shell Injection

For getting injection in your controllers to work you need to add the following line of your bin/cake.php:, (*8)

$commandFactory = new \PipingBag\Console\DICommandFactory();
$runner = new CommandRunner(new Application(dirname(__DIR__) . '/config'), 'cake', $commandFactory);

Additionally, you can configure the modules to be used and caching options in your config/app.php file., (*9)

'PipingBag' => [
    'modules' => ['MyWebModule', 'AnotherModule', 'APlugin.SuperModule'],
    'cacheConfig' => 'default'
]

Modules can also be returned as instances in the configuration array:, (*10)

'PipingBag' => [
    'modules' => [new App\Di\Module\MyWebModule()],
    'cacheConfig' => 'default'
]

Finally, if you wish to tune your modules before they are registered, you can use a callable function:, (*11)

'PipingBag' => [
    'modules' => function () {
        return [new MyWebModule()];
    },
    'cacheConfig' => 'default'
]

What is a Module anyway?

Modules are classes that describe how instances and their dependencies should be constructed, they provide a natural way of grouping configurations. An example module looks like this:, (*12)

// in app/src/Di/Module/MyModule.php

namespace App\Di\Module;

use Ray\Di\AbstractModule;

class MyModule extends AbstractModule
{
    public function configure()
    {
        $this->bind('MovieApp\FinderInterface')->to('MovieApp\Finder');
        $this->bind('MovieApp\HttpClientInterface')->to('Guzzle\HttpClient');
        $this->install(new OtherModule()); // Modules can install other modules
    }
}

Modules are, by convention, placed in your src/Di/Module folder. Read more about creating modules and how to bind instances to names in the Official Ray.Di Docs., (*13)

Usage

After creating and passing the modules in the configuration, you can get instance of any class and have their dependencies resolved following the rules created in the modules:, (*14)

use PipingBag\Di\PipingBag;

$httpClient = PipingBag::get('MovieApp\HttpClientInterface');

Injecting Dependencies in Controllers

Ray.Di is able to inject instances to your controllers based on annotations:, (*15)

// in src/Controller/ArticlesController.php

use App\Controller\AppController;
use MovieApp\HttpClientInterface;
use Ray\Di\Di\Inject; // This is important

class ArticlesController extends AppController
{
    /**
     * @Inject
     */
    public function setHttpClient(HttpClientInterface $connection)
    {
        $this->httpClient = $connection;
    }
}

As soon as the controller is created, all methods having the @Inject annotation will get instances of the hinted class passed. This works for constructors as well., (*16)

Injecting Dependencies in Controller Actions

It is also possible to inject dependencies directly in the controller actions. When doing this, add the type-hinted dependency to the end of the arguments and set the default value to null, it is also required to annotate the method using @Assisted, (*17)

// in src/Controller/ArticlesController.php

use App\Controller\AppController;
use MovieApp\HttpClientInterface;
use PipingBag\Annotation\Assisted; // This is important

class ArticlesController extends AppController
{
    /**
     * @Assisted
     */
    public function edit($id, HttpClientInterface $connection = null)
    {
        $article = $this->Articles->get($id)
        $connection->post(...);
    }
}

Injecting Dependencies in Shells

Shells are also able to receive dependencies via the @Inject annotation. But first, you need to change the cake console executable to use PipingBag. Open your bin/cake.php file and make it look like this:, (*18)

// bin/cake.php
...
exit(PipingBag\Console\ShellDispatcher::run($argv)); // Changed namespace of ShellDispatcher

Then you can apply annotations to your shells:, (*19)

use Cake\Console\Shell;
use Ray\Di\Di\Inject; // This is important

class MyShell extends Shell
{
    /**
     * @Inject
     */
    public function setHttpClient(HttpClientInterface $connection)
    {
        $this->httpClient = $connection;
    }
}

The Versions

23/05 2017

dev-master

9999999-dev

CakePHP 3 plugin for using Ray.Di as a Dependency Injection Container

  Sources   Download

MIT

The Requires

 

The Development Requires

23/05 2017

1.1

1.1.0.0

CakePHP 3 plugin for using Ray.Di as a Dependency Injection Container

  Sources   Download

MIT

The Requires

 

The Development Requires

20/07 2016

1.0.2

1.0.2.0

CakePHP 3 plugin for using Ray.Di as a Dependency Injection Container

  Sources   Download

MIT

The Requires

 

The Development Requires

18/01 2016

1.0.1

1.0.1.0

CakePHP 3 plugin for using Ray.Di as a Dependency Injection Container

  Sources   Download

MIT

The Requires

 

The Development Requires

12/06 2015

1.0.0

1.0.0.0

CakePHP 3 plugin for using Ray.Di as a Dependency Injection Container

  Sources   Download

MIT

The Requires

 

The Development Requires