PHPackages                             lorenzo/piping-bag - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. lorenzo/piping-bag

ActiveCakephp-plugin[Framework](/categories/framework)

lorenzo/piping-bag
==================

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

2.0(5y ago)35118.3k—4.4%9[1 issues](https://github.com/lorenzo/piping-bag/issues)1MITPHPCI failing

Since Jun 12Pushed 5y ago3 watchersCompare

[ Source](https://github.com/lorenzo/piping-bag)[ Packagist](https://packagist.org/packages/lorenzo/piping-bag)[ RSS](/packages/lorenzo-piping-bag/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (5)Dependencies (2)Versions (6)Used By (1)

Dependency Injection Container Plugin for CakePHP 4
===================================================

[](#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.

It uses the clean and flexible [Ray.Di Library](https://github.com/ray-di/Ray.Di) which is a PHP dependency injection framework in the style of "Google Guice".

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.

Installation
------------

[](#installation)

You can install this plugin into your CakePHP application using [composer](http://getcomposer.org).

```
composer require lorenzo/piping-bag=dev-master
```

Configuration
-------------

[](#configuration)

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

[](#upgrading-from-library-version-1x-cake-3x)

**DEPRECATED:**

- `ControllerFactoryFilter.php` for injecting controllers
- `ShellDispatcher.php` for injecting shell classes

Remove the following lines in your: `config/bootstrap.php`:

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

### Controller Injection

[](#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`:

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

### Shell Injection

[](#shell-injection)

For getting injection in your controllers to work you need to add the following line of your `bin/cake.php`:

```
$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.

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

Modules can also be returned as instances in the configuration array:

```
'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:

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

What is a Module anyway?
------------------------

[](#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:

```
// 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](https://github.com/ray-di/Ray.Di#getting-started).

Usage
-----

[](#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:

```
use PipingBag\Di\PipingBag;

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

### Injecting Dependencies in Controllers

[](#injecting-dependencies-in-controllers)

Ray.Di is able to inject instances to your controllers based on annotations:

```
// 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.

### Injecting Dependencies in Controller Actions

[](#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`

```
// 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

[](#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:

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

Then you can apply annotations to your shells:

```
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;
    }
}
```

###  Health Score

41

—

FairBetter than 89% of packages

Maintenance19

Infrequent updates — may be unmaintained

Popularity43

Moderate usage in the ecosystem

Community21

Small or concentrated contributor base

Maturity67

Established project with proven stability

 Bus Factor1

Top contributor holds 79.6% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~498 days

Total

5

Last Release

2001d ago

Major Versions

1.1 → 2.02020-11-25

### Community

Maintainers

![](https://www.gravatar.com/avatar/5b4694a64f9dab01ec0e776946b15c84113dee8a51344f1c394f40bd7a453312?d=identicon)[lorenzo](/maintainers/lorenzo)

---

Top Contributors

[![lorenzo](https://avatars.githubusercontent.com/u/37621?v=4)](https://github.com/lorenzo "lorenzo (43 commits)")[![WyriHaximus](https://avatars.githubusercontent.com/u/147145?v=4)](https://github.com/WyriHaximus "WyriHaximus (4 commits)")[![amayer5125](https://avatars.githubusercontent.com/u/3212673?v=4)](https://github.com/amayer5125 "amayer5125 (3 commits)")[![vanoostrum](https://avatars.githubusercontent.com/u/3648455?v=4)](https://github.com/vanoostrum "vanoostrum (1 commits)")[![koriym](https://avatars.githubusercontent.com/u/529021?v=4)](https://github.com/koriym "koriym (1 commits)")[![antograssiot](https://avatars.githubusercontent.com/u/4977112?v=4)](https://github.com/antograssiot "antograssiot (1 commits)")[![aydot](https://avatars.githubusercontent.com/u/5358010?v=4)](https://github.com/aydot "aydot (1 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/lorenzo-piping-bag/health.svg)

```
[![Health](https://phpackages.com/badges/lorenzo-piping-bag/health.svg)](https://phpackages.com/packages/lorenzo-piping-bag)
```

###  Alternatives

[nolimits4web/swiper

Most modern mobile touch slider and framework with hardware accelerated transitions

41.8k177.2k1](/packages/nolimits4web-swiper)[laravel/dusk

Laravel Dusk provides simple end-to-end testing and browser automation.

1.9k36.7M259](/packages/laravel-dusk)[laravel/prompts

Add beautiful and user-friendly forms to your command-line applications.

712181.8M596](/packages/laravel-prompts)[cakephp/chronos

A simple API extension for DateTime.

1.4k47.7M121](/packages/cakephp-chronos)[laravel/pail

Easily delve into your Laravel application's log files directly from the command line.

91545.3M590](/packages/laravel-pail)[nette/bootstrap

🅱 Nette Bootstrap: the simple way to configure and bootstrap your Nette application.

68535.8M592](/packages/nette-bootstrap)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
