PHPackages                             divineniiquaye/rade-di - 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. [PSR &amp; Standards](/categories/psr-standards)
4. /
5. divineniiquaye/rade-di

ActiveLibrary[PSR &amp; Standards](/categories/psr-standards)

divineniiquaye/rade-di
======================

A simple and smart dependency injection for PHP

v0.2.3(5y ago)41.4k2[2 PRs](https://github.com/biurad/php-di/pulls)BSD-3-ClausePHPPHP ^7.4 || ^8.0CI passing

Since Jan 25Pushed 1w ago1 watchersCompare

[ Source](https://github.com/biurad/php-di)[ Packagist](https://packagist.org/packages/divineniiquaye/rade-di)[ Docs](https://www.divinenii.com)[ Fund](https://biurad.com/sponsor)[ Patreon](https://www.patreon.com/biurad)[ RSS](/packages/divineniiquaye-rade-di/feed)WikiDiscussions master Synced 2d ago

READMEChangelog (10)Dependencies (11)Versions (14)Used By (0)

The PHP Rade DI
===============

[](#the-php-rade-di)

[![PHP Version](https://camo.githubusercontent.com/6586a351faff745fd1bf852ecd4e9dd88c6e63d14ee77eea108c01c2f1df0f2c/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f646976696e656e696971756179652f726164652d64692e7376673f7374796c653d666c61742d73717561726526636f6c6f72423d253233383839324246)](http://php.net)[![Latest Version](https://camo.githubusercontent.com/3f4222e8d089562c913c346bb2fd9f420f5b4895c9e44b0171aa084ced0b81e7/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f646976696e656e696971756179652f726164652d64692e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/divineniiquaye/rade-di)[![Workflow Status](https://camo.githubusercontent.com/b63dae1d9e976217635f3846f046da91befc6b01630042b32c5d546372a41045/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f776f726b666c6f772f7374617475732f646976696e656e696971756179652f726164652d64692f6275696c643f7374796c653d666c61742d737175617265)](https://github.com/divineniiquaye/rade-di/actions?query=workflow%3Abuild)[![Code Maintainability](https://camo.githubusercontent.com/fe78a014bd794b5fb51019af60488349ede5488f1a66b60ce66c4e1b052c5c08/68747470733a2f2f696d672e736869656c64732e696f2f636f6465636c696d6174652f6d61696e7461696e6162696c6974792f646976696e656e696971756179652f726164652d64693f7374796c653d666c61742d737175617265)](https://codeclimate.com/github/divineniiquaye/rade-di)[![Coverage Status](https://camo.githubusercontent.com/7d0a000d8a36a8b9f870d09efea31c555f89afafdb4dfd7fb44f4f693d234b52/68747470733a2f2f696d672e736869656c64732e696f2f636f6465636f762f632f6769746875622f646976696e656e696971756179652f726164652d64693f7374796c653d666c61742d737175617265)](https://codecov.io/gh/divineniiquaye/rade-di)[![Psalm Type Coverage](https://camo.githubusercontent.com/7facd2e46e1fe9947c8ecbe69e238e3bea532861bad3a35a45612cfc78e9e818/68747470733a2f2f696d672e736869656c64732e696f2f656e64706f696e743f7374796c653d666c61742d7371756172652675726c3d687474707325334125324625324673686570686572642e646576253246676974687562253246646976696e656e69697175617965253246726164652d6469253246636f766572616765)](https://shepherd.dev/github/divineniiquaye/rade-di)[![Quality Score](https://camo.githubusercontent.com/8f121e5dc042bd2c665838667212246ac68526376b01a5f1a45bf3c8d6a14340/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f672f646976696e656e696971756179652f726164652d64692e7376673f7374796c653d666c61742d737175617265)](https://scrutinizer-ci.com/g/divineniiquaye/rade-di)

---

**divineniiquaye/rade-di** is a HIGH performance smart tool for performing simple to complex dependency injection in your application for [PHP](https://php.net) 7.4+ created by [Divine Niiquaye](https://github.com/divineniiquaye) referenced to [Nette DI](https://github.com/nette/di) and [Pimple](https://github.com/silexphp/pimple). This library provides an advance way of resolving services for best performance to your application.

Rade DI was born after frustration using [Symfony DI](https://github.com/symfony/dependency-injection) and [Nette DI](https://github.com/nette/di) on several projects. Autowiring feature in Nette is much more simpler than that of symfony's. No doubt they all great to use, but I wanted a DI which allows me focus on writing code than configuring the DI. Initially was a simple container, but over time managed to include most essential features.

This project adheres to a [code of conduct](CODE_OF_CONDUCT.md). By participating in this project and its community, you are expected to uphold this code.

📦 Installation &amp; Basic Usage
--------------------------------

[](#-installation--basic-usage)

This project requires [PHP](https://php.net) 7.4 or higher. The recommended way to install, is via [Composer](https://getcomposer.org). Simply run:

```
$ composer require divineniiquaye/rade-di
```

Creating a container is a matter of creating a `Container` instance:

```
use Rade\DI\Container;

$container = new Container();
```

For registering services into container, a service must be a real valid PHP object type. Container implements both PSR-11 `ContainerInterface` and `ArrayAccess`, so here's an example to demonstrate:

> Using Container without `ArrayAccess`

```
use function Rade\DI\Loader\{service, wrap};

// define some services
$container->set('session_storage', new SessionStorage('SESSION_ID'));
// or this for default autowiring typed support
$container->autowire('session_storage', new SessionStorage('SESSION_ID'));

$container->set('session', static fn(): Session => new Session($container['session_storage']));
// or
$container->set('session', wrap(Session::class));
// or further for autowiring
$container->set('session', service(Session::class))->autowire();
```

> Using Container with `ArrayAccess`

```
use Rade\DI\Definition;

// define some services
$container['session_storage'] = new SessionStorage('SESSION_ID');

$container['session'] = fn(): Session => new Session($container['session_storage']);
// or
$container['session'] = new Definition(Session::class);
// or
$container['session'] = $container->call(Session::class);
// or further
$container['session'] = new Session($container['session_storage']);
```

Using the defined services is also very easy:

```
// get the session object
$session = $container->get('session');
// or using ArrayAccess
$session = $container['session'];
// or use it's service class name, parent classes or interfaces
$session = $container->get(Session::class);

// the above call is roughly equivalent to the following code:
$storage = new SessionStorage('SESSION_ID');
$session = new Session($storage);
```

Container supports reuseable service instance. This is means, a registered service which is resolved, is frozen and object's id does not change throughout your application using Rade DI.

Rade DI also supports autowiring except a return type of a callable is not define or better still if you do not want autowiring at all, use the container's **set** method. By default, registering services with `ArrayAccess` implementation are all autowired.

```
use function Rade\DI\Loader\{service, reference};

$container['session'] = service(Session::class, [reference('session_storage')])->shared(false);
```

With the example above, each call to `$container['session']` returns a new instance of the session. Also Rade has aliasing and tagging support for services. If you want to add a different name to a registered service, use `alias` method.

```
$container['film'] = new Movie('S1', 'EP202');
$container->alias('movie', 'film');

// Can be access by $container['film'] or $container['movie']
```

For tagging, perhaps you are building a report aggregator that receives an array of many different `Report` interface implementations.

```
$container['speed.report'] = new SpeedReport(...);
$container['memory.report'] = new MemoryReport(...);

$container->tags(['reports' => ['speed.report', 'memory.report']]);
// or if autowired or not
$container->tags(['reports' => [SpeedReport::class, MemoryReport::class]]);
```

Once the services have been tagged, you may easily resolve them all via the `tagged` method:

```
$tags = $container->tagged('reports');
$reports = [];

foreach ($tags as $report => $attr) {
    $reports[] = $report;
}

$manager = new ReportAggregator($reports);

// For the $attr var, this is useful if you need tag to have extra values. eg:
$container->tags(['process' => [BackupProcessor::class, MonitorProcessor::class, CacheProcessor::class => false]]);

foreach ($container->tagged('process') as $process => $enabled) {
    if ($enabled) {
        $manager->addProcessor($container->get($process));
    }
}
```

Since PHP 8 release, container supports injecting services to public class properties and public class methods using an attribute named `#[Inject]`. If a value is not provided for the attribute it uses type declaration on either public class properties or public class methods typed parameter(s).

For performance reasons, this feature is locked to classes implementing `Rade\DI\Injector\InjectableInterface`, and can be resolved using the container's call method or container resolver's resolveClass method.

Eg: Dependency `Service1` will be passed by calling the `injectService1` method, dependency `Service2` will be assigned to the `$service2` property:

```
use Rade\DI\Attribute\Inject;
use Rade\DI\Injector\InjectableInterface;

class FooClass implements InjectableInterface
{
    #[Inject]
	public Service2 $service2;

    private Service1 $service1;

    #[Inject]
	public function injectService1(Service1 $service)
	{
		$this->service1 = $service1;
	}

    public function getService1(): Service1
    {
        return $this->service1;
    }
}
```

> Before the PHP's 8 #\[Inject\] attribute, rade di supported autowiring using phpdoc type and still support's with plans to remove after PHP 8.2 release. The #\[Inject\] attribute is an advanced autowiring, as long as the value is resolvable by the container, it doesn't mind.

Rade Di has extensions support, which allows the container to be extensible and reuseable. With Rade DI, your project do not need so to depend on PSR-11 container so much. Using service providers in your project, saves you alot.

```
use Rade\DI\Container;

class FooProvider implements Rade\DI\Extensions\ExtensionInterface
{
    /**
     * {@inheritdoc}
     */
    public function register(AbstractContainer $container, array $configs = []): void
    {
        // register some services and parameters
        // on $container
    }
}
```

Then, register the provider on a Container:

```
$container->register(new FooProvider());
```

Service providers support [Symfony's config component](https://github.com/symfony/config) for writing configuration for service definitions found in a provider. Implement the service provider class to `Symfony\Component\Config\Definition\ConfigurationInterface`.

Writing configurations for a service provider by default, the service provider's class name, becomes the key pointing to the require config data. Want to use a custom key name, set add a static **getId** method returning your custom key name.

> Using [Symfony's config component](https://github.com/symfony/config) + `Rade\DI\ContainerBuilder` class is highly recommended.

```
$ composer require symfony/config
```

Also the `Rade\DI\ServiceLocator` class is intended of setting predefined services while instantiating them only when actually needed.

For service locators, Rade uses [symfony's service contracts](https://github.com/symfony/service-contracts).

It also allows you to make your services available under different naming. For instance, you may want to use an object that expects an instance of `EventDispatcherInterface` to be available under the name `event_dispatcher` while your event dispatcher has been registered under the name `dispatcher`:

```
use Monolog\Logger;
use Rade\DI\ServiceLocator;
use Psr\Container\ContainerInterface;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Contracts\Service\ServiceSubscriberInterface;

class MyService implements ServiceSubscriberInterface
{
    /**
     * "logger" must be an instance of Psr\Log\LoggerInterface
     * "event_dispatcher" must be an instance of Symfony\Component\EventDispatcher\EventDispatcherInterface
     */
    public function __construct(private ServiceProviderInterface $container = null)
    {
    }

    /**
     * {@inheritdoc}
     */
    public static function getSubscribedServices(): array
    {
        return ['logger', 'event_dispatcher' => 'dispatcher'];
    }
}

$container['logger'] = new Monolog\Logger();
$container['dispatcher'] = new EventDispatcher();

$container['service'] = MyService::class;
```

📓 Documentation
---------------

[](#-documentation)

For in-depth documentation before using this library. Full documentation on advanced usage, configuration, and customization can be found at [docs.divinenii.com](https://docs.divinenii.com/rade-di).

⏫ Upgrading
-----------

[](#-upgrading)

Information on how to upgrade to newer versions of this library can be found in the [UPGRADE](UPGRADE-1.x.md).

🏷️ Changelog
------------

[](#️-changelog)

[SemVer](http://semver.org/) is followed closely. Minor and patch releases should not introduce breaking changes to the codebase; See [CHANGELOG](CHANGELOG-0.x.md) for more information on what has changed recently.

Any classes or methods marked `@internal` are not intended for use outside of this library and are subject to breaking changes at any time, so please avoid using them.

🛠️ Maintenance &amp; Support
----------------------------

[](#️-maintenance--support)

(This policy may change in the future and exceptions may be made on a case-by-case basis.)

- A new **patch version released** (e.g. `1.0.10`, `1.1.6`) comes out roughly every month. It only contains bug fixes, so you can safely upgrade your applications.
- A new **minor version released** (e.g. `1.1`, `1.2`) comes out every six months: one in June and one in December. It contains bug fixes and new features, but it doesn’t include any breaking change, so you can safely upgrade your applications;
- A new **major version released** (e.g. `1.0`, `2.0`, `3.0`) comes out every two years. It can contain breaking changes, so you may need to do some changes in your applications before upgrading.

When a **major** version is released, the number of minor versions is limited to five per branch (X.0, X.1, X.2, X.3 and X.4). The last minor version of a branch (e.g. 1.4, 2.4) is considered a **long-term support (LTS) version** with lasts for more that 2 years and the other ones cam last up to 8 months:

**Get a professional support from [Biurad Lap](https://biurad.com) after the active maintenance of a released version has ended**.

🧪 Testing
---------

[](#-testing)

```
$ ./vendor/bin/phpunit
```

This will tests divineniiquaye/rade-di will run against PHP 7.4 version or higher.

🏛️ Governance
-------------

[](#️-governance)

This project is primarily maintained by [Divine Niiquaye Ibok](https://github.com/divineniiquaye). Contributions are welcome 👷‍♀️! To contribute, please familiarize yourself with our [CONTRIBUTING](./.github/CONTRIBUTING.md) guidelines.

To report a security vulnerability, please use the [Biurad Security](https://security.biurad.com). We will coordinate the fix and eventually commit the solution in this project.

🙌 Sponsors
----------

[](#-sponsors)

Are you interested in sponsoring development of this project? Reach out and support us on [Patreon](https://www.patreon.com/biurad) or see  for a list of ways to contribute.

👥 Credits &amp; Acknowledgements
--------------------------------

[](#-credits--acknowledgements)

- [Divine Niiquaye Ibok](https://github.com/divineniiquaye)
- [All Contributors](https://github.com/divineniiquaye/rade-di/contributors)

📄 License
---------

[](#-license)

The **divineniiquaye/rade-di** library is copyright © [Divine Niiquaye Ibok](https://divinenii.com) and licensed for use under the [![Software License](https://camo.githubusercontent.com/d8c1f1b4c1b899449e9539d4de1ca66abde4c190f41ce41e7abc3330da5cad2e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4253442d2d332d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](LICENSE).

###  Health Score

40

—

FairBetter than 88% of packages

Maintenance64

Regular maintenance activity

Popularity21

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity55

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 99.8% 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 ~5 days

Total

11

Last Release

1881d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/a71bed376af70d8c5eeb12c80cfb4bf428f70e48301fb2bba1d4a87009e20eeb?d=identicon)[divineniiquaye](/maintainers/divineniiquaye)

---

Top Contributors

[![divineniiquaye](https://avatars.githubusercontent.com/u/53147395?v=4)](https://github.com/divineniiquaye "divineniiquaye (806 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (2 commits)")

---

Tags

biuradcontainerdependency-injectiondiphpphpcontainerdependency-injectiondibiuradbiuradphp

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan, Psalm

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/divineniiquaye-rade-di/health.svg)

```
[![Health](https://phpackages.com/badges/divineniiquaye-rade-di/health.svg)](https://phpackages.com/packages/divineniiquaye-rade-di)
```

PHPackages © 2026

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