jnjxp / container
jnjxp container package
Installs: 1 320
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 1
Forks: 0
Open Issues: 0
Requires
- php: ^8.0
- container-interop/service-provider: ^0.4.0
- psr/container: ^1.1.1 || ^2.0.2
Requires (Dev)
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^12.0
- squizlabs/php_codesniffer: ^3.11
- vimeo/psalm: ^6.4
Provides
This package is auto-updated.
Last update: 2025-03-16 02:23:12 UTC
README
Yet another dependency injection container.
Install
$ composer require jnjxp/container
Usage
Factories
Define how to create entries based on string identifier.
// Given use Jnjxp\Container\Container; class Foo { public function __construct(public int $dependency) { } } class Bar extends Foo { } class BarFactory { public function __invoke() { return new Bar(1); } } // Configure Container $factories = [ Foo::class => fn() => new Foo(1), // callable Bar::class => BarFactory::class, // string identifier ]; $container = new Container(factories: $factories); // Use Container $foo = $container->get(Foo::class); $bar = $container->get(Bar::class); print_r($foo); print_r($bar); // Foo Object // ( // [dependency] => 1 // ) // Bar Object // ( // [dependency] => 1 // )
Resolving Dependencies
Container
is passed to factories.
// Given use Jnjxp\Container\Container; use Psr\Container\ContainerInterface as CI; class Foo { public function __construct(public Bar $bar) { } } class Bar {} // Configure Container $factories = [ Foo::class => fn(CI $container) => new Foo($container->get(Bar::class)), Bar::class => fn() => new Bar(), ]; $container = new Container(factories: $factories); // Use Container $foo = $container->get(Foo::class); print_r($foo); // Foo Object // ( // [bar] => Bar Object // ( // ) // // )
Aliases
Add additional identifiers to entries.
// Given use Jnjxp\Container\Container; interface FooInterface {} class Foo implements FooInterface {} // Configure Container $factories = [ Foo::class => fn() => new Foo() ]; $aliases = [ FooInterface::class => Foo::class ]; $container = new Container( factories: $factories, aliases: $aliases, ); // Use Container $foo = $container->get(FooInterface::class); print_r($foo); // Foo Object // ( // )
Existing Instances
Container won't look for factories or extensions.
// Given use Jnjxp\Container\Container; // Configure Container $instances = [ 'FOO' => 'foo' ]; $container = new Container( instances: $instances, ); // Use Container $foo = $container->get('FOO'); echo "$foo\n"; //foo
Extensions
- Should be an
array
of callables or identifiers that resolve to them. - 1st parameter is the
Container
, 2nd is the existing Instance. (should be swapped) - The entry will be replaced by what is returned from the extension.
// Given use Jnjxp\Container\Container; use Psr\Container\ContainerInterface as CI; class Foo {} class FooDecorator { public function __construct(public Foo $foo) { } } class Bar { public $bar ; } // Configure Container $extensions = [ Foo::class => [ fn(CI $container, Foo $foo) => new FooDecorator($foo) ], Bar::class => [ function(CI $container, Bar $bar) { $bar->bar = 1 ; return $bar; } ], ]; $container = new Container( extensions: $extensions, ); // Use Container $foo = $container->get(Foo::class); $bar = $container->get(Bar::class); print_r($foo); print_r($bar); // FooDecorator Object // ( // [foo] => Foo Object // ( // ) // // ) // Bar Object // ( // [bar] => 1 // )
Autowire
Enable auto-wiring by providing an AutowireInterface
// Given use Jnjxp\Container\Container; use Jnjxp\Container\Autowire\Autowire; class Foo { public function __construct(public Bar $bar) { } } class Bar { } // Configure Container $autowire = new Autowire(); $container = new Container( autowire: $autowire, ); // Use Container $foo = $container->get(Foo::class); print_r($foo); // Foo Object // ( // [bar] => Bar Object // ( // ) // // )
AutowireInterface
use Psr\Container\ContainerInterface; interface AutowireInterface { public function create(string $className, ?ContainerInterface $container = null): object; }
Builder
User ContainerBuilder
to build a Container
.
use Jnjxp\Container\ContainerBuilder; $builder = new Builder(); // set factories $builder->factory($name, $factory); $builder->factories($factories); // set aliases $builder->alias($alias, $identifier); $builder->aliases($aliases); //set instances $builder->instance($name, $instance); $builder->instances($instances); // set extensions $builder->extension($name, $extension); $builder->extensions($extensions); // enable auto-wiring $builder->autowire(true); $builder->autowire($autowireImplementation); // disable auto-wiring $builder->autowire(false); // Bulid the Container $container = $builder->build();
Service Providers
Service Providers can define factories and extensions in the ContainerBuilder
.
See container-interop/service-provider.
ServiceProviderInterface
namespace Interop\Container; interface ServiceProviderInterface { public function getFactories(); public function getExtensions(); }
Service Provider Example
// Given use Jnjxp\Container\ContainerBuilder; use Jnjxp\Container\ServiceProvider\BaseServiceProvider; class Foo { public function __construct(public int $dependency) { } } class ServiceProvider extends BaseServiceProvider { public function getFactories(): array { return [ Foo::class => fn() => new Foo(1) ]; } } $builder = new ContainerBuilder(); $builder->provider(ServiceProvider::class); $container = $builder->build(); $foo = $container->get(Foo::class); print_r($foo); // Foo Object // ( // [dependency] => 1 // )