https://github.com/selective-php/container
A PSR-11 container implementation with factories and autowiring
https://github.com/selective-php/container
autowire autowiring container dependency-injection factories php psr-11 slim slim4
Last synced: 2 days ago
JSON representation
A PSR-11 container implementation with factories and autowiring
- Host: GitHub
- URL: https://github.com/selective-php/container
- Owner: selective-php
- License: mit
- Created: 2020-05-02T22:56:43.000Z (almost 5 years ago)
- Default Branch: master
- Last Pushed: 2023-09-09T16:58:24.000Z (over 1 year ago)
- Last Synced: 2024-09-23T08:09:11.494Z (7 months ago)
- Topics: autowire, autowiring, container, dependency-injection, factories, php, psr-11, slim, slim4
- Language: PHP
- Homepage:
- Size: 49.8 KB
- Stars: 12
- Watchers: 3
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# selective/container
[](https://packagist.org/packages/selective/container)
[](LICENSE)
[](https://github.com/selective-php/container/actions)
[](https://scrutinizer-ci.com/g/selective-php/container/code-structure)
[](https://scrutinizer-ci.com/g/selective-php/container/?branch=master)
[](https://packagist.org/packages/selective/container/stats)## Description
A PSR-11 container implementation with optional **autowiring**.
## Requirements
* PHP 8.1+
## Installation
```
composer require selective/container
```## Usage
```php
use Selective\Container\Container;$container = new Container();
// ...$myService = $container->get(MyService::class);
```### Enable Autowiring
The container is able to automatically create and inject dependencies for you. This is called "autowiring".
To enable autowiring you have to add the `ConstructorResolver`:
```php
addResolver(new ConstructorResolver($container));//...
```
### Defining DI Container Definitions
You can use a factories (closures) to define injections.
```php
factory(MyService::class, function (ContainerInterface $container) {
return new MyService();
});
```## Defining Multiple DI Container Definitions
```php
use Psr\Container\ContainerInterface;
// ...$entries = [
MyService::class => function (ContainerInterface $container) {
return new MyService();
},
PDO::class => function (ContainerInterface $container) {
return new PDO('sqlite:example.db');
},
// and so on...
];$container->factories($entries);
```### Service Providers
Service providers give the benefit of organising your container
definitions along with an increase in performance for larger applications
as definitions registered within a service provider are lazily registered
at the point where a service is retrieved.To build a service provider create a invokable class and
return the definitions (factories) you would like to register.```php
*/
public function __invoke(): array
{
return [
MyService::class => function (ContainerInterface $container) {
return new MyService($container->get(LoggerInterface::class));
},
];
}
}$container->factories((new MyServiceFactoryProvider())());
```### Set definitions directly
In addition to defining entries in an array of factories / callbacks,
you can also set the value directly as shown below:```php
$container->set(\App\Domain\MyService::class, new \App\Domain\MyService());
```### Fetching DI container entries
To fetch a value use the `get` method:
```php
$pdo = $container->get(PDO::class);
```### Testing
* Make sure that your container will be recreated for each test. You may use the phpunit `setUp()` method to initialize the container definitions.
* You can use the `set()` method to overwrite existing container entries.#### Mocking
The `set` method can also be used to set mocked objects directly into the container.
This example requires phpunit:
```php
getMockBuilder($class)
->disableOriginalConstructor()
->getMock();$mock->method('methodToMock1')->willReturn('foo');
$mock->method('methodToMock2')->willReturn('bar');$container->set($class, $mock);
```## Slim 4 integration
Example to boostrap a Slim 4 application using the container:
```php
addResolver(new ConstructorResolver($container));// Load container definitions
$container->factories(require __DIR__ . '/container.php');// Create slim app instance
AppFactory::setContainer($container);
$app = AppFactory::create();// Add routes, middleware etc...
$app->run();
```The `container.php` file must return an array of factories (closures):
```php
function () {
return require __DIR__ . '/settings.php';
},LoggerInterface::class => function (ContainerInterface $container) {
$logger = new Logger('name');
// ...
return $logger;
},
// Add more definitions here...
]
```## PhpStorm Integration
If you use PhpStorm, then create a new file `.phpstorm.meta.php`
in your project root directory and copy/paste the following content:```php
'@']));
```## Performance Comparison
`selective/container` is about:
* 11% faster then `php-di/php-di`.
* 5.4% faster then `league/container`.All tests where made with enabled autowiring.
## Migrating from PHP-DI
This PSR-11 container implementation mimics the behavior of PHP-DI.
If you already use [factories](https://php-di.org/doc/php-definitions.html#factories) for your container definitions,
the switch should be very simple.Replace this:
```php
addDefinitions(__DIR__ . '/container.php');$container = $containerBuilder->build();
```... with this:
```php
addResolver(new ConstructorResolver($container));// Add definitions
$container->factories(require __DIR__ . '/container.php');
```That's it.
## Credits
* Dominik Zogg (chubbyphp)
## Similar libraries
* https://github.com/chubbyphp/chubbyphp-container
* http://php-di.org/
* https://container.thephpleague.com/## License
The MIT License (MIT). Please see [License File](LICENSE) for more information.