liftkit / dependency-injection
Dependency injection library for LiftKit
Installs: 1 692
Dependents: 4
Suggesters: 0
Security: 0
Stars: 0
Watchers: 2
Forks: 0
Open Issues: 0
Requires
- psr/container: ^1.0
Requires (Dev)
- phpunit/dbunit: ^1.2
- phpunit/phpunit: ^4.5
This package is auto-updated.
Last update: 2024-10-15 15:13:00 UTC
README
A simple but featured dependency injection library, with automatic class-resolution.
Create a new container
use LiftKit\DependencyInjection\Container\Container; $container = new Container;
Rules
A rule is an anonymous function that defines how to create an object.
$container->setRule( 'SomeRule', function () { return new SomeClass(); } ); $someObject = $container->getObject('SomeRule'); // $someObject will be an instance of SomeClass
Singleton rules
A rule will execute each time getObject
is called by default. In order to force it to
execute only once, we use setSingletonRule
. Each call to getObject
for the rule will return
the same object.
$container->setSingletonRule( 'SomeSingletonRule', function () { return new SomeClass(); } ); $object1 = $container->getObject('SomeSingletonRule'); $object2 = $container->getObject('SomeSingletonRule'); // $object1 and $object2 are the same object
Rules with parameters
Some rules can have parameters passed to them. The first argument to the setRule
callback is the
container istelf. Each subsequent argument is supplied by an optional array of parameters supplied
to getObject
.
$container->setRule( 'SomeRuleWithParameters', function (Container $container, $arg1, $arg2) { return new SomeClass($arg1, $arg2); } ); $someObject = $container->getObject('SomeRuleWithParameters', ['arg1', 'arg2']); // SomeClass will be contructed with 'arg1' and 'arg2' as the parameters to is constructor.
Rules that reference other rules
$container->setRule( 'Rule1', function () { return new SomeClass; } ); $container->setRule( 'Rule2', function (Container $container) { return new OtherClass($container->getObject('Rule1')); } ); $someObject = $container->getObject('Rule2'); // $someObject will be an instance of OtherClass with a new instance of SomeClass injected as its // first contructor argument.
Overriding rules
Rules can be overridden by redefining them. This is useful for modular code.
$conatiner->setRule( 'SomeRule', function () { return new SomeClass; } ); $container->setRule( 'SomeRule', function () { return new OtherClass; } ); $someObject = $container->getObject('SomeRule'); // $someobject will be an instance of OtherClass
Storing an instance
You can also store an object you've already created an bind it to a rule.
$someObject = new SomeObject; $container->storeObject('SomeRule', $someObject); $otherObject = $container->getObject('SomeRule'); // $someObject and $otherObject are the some object
Automatic resolution
The container can also bind a rule to a class. An instance of a class
can be created automatially by looking at the typehints of each
constructor argument. In the case below, and instance of B
is
automatically created before creating an instance of A
. The newly-created instance of B is then injected into the constructor of A
.
class A { private $b; public function __construct (B $b) { $this->b = $b; } public function getB () { return $this->b; } } class B { // placeholder class } $container->bindRuleToClass( 'GiveMeANewA', A::class ); $a = $container->getObject('GiveMeANewA'); $b = $a->getB(); // $a is a new instance of A. $b is a new instance of b.
Automatic resolution with rules
In some cases, you may need to tell the injector to create an instance following a different rule when it encounters the
typehint of a certain class instead. In the example below, a rule is created for the construction of B
. When the container realizes it needs an instance of B
when creating an A
, it will follow that rule to create B
first. In this case, A
's constructor was injected with an instance of B created by the rule 'GiveMeANewB'
to create $a
.
$container->setRule( 'GiveMeANewB', function () { $b = new B; $b->createdByRule = true; return $b; } ); $container->bindClassToRule( B::class, 'GiveMeANewB' ); $a = $container->getObject('GiveMeANewA'); $b = $a->getB(); // $b->createdByRule is true
Automatic resolution with parameters
Sometimes, there are additional parameters that need to be passed to the constructor of a new instance that is being automatically constructed. Below the variables $param1
and $param2
will be injectied into C
's constructor, while B
will be created by the rule 'GiveMeANewB'
above. Any additional parameters must fall at the end of the constructor's list of parameters.
class C { private $b; private $param1; private $param2; public function __construct (B $b, $param1, $param2) { $this->b = $b; $this->param1 = $param1; $this->param2 = $param2; } public function getB () { return $this->b; } public function getParam1 () { return $this->param1; } public function getParam2 () { return $this->param2; } } $container->bindRuleToClass( 'GiveMeANewC', C::class ); $param1 = 1; $param2 = 2; $c = $container->getObject( 'GiveMeANewC', [ $param1, $param2, ] ); $b = $c->getB(); $cParam1 = $c->getParam1(); $cParam2 = $c->getParam2(); // $b is an instance of B // $cParam1 is 1 // $cParam2 is 2
Binding classes to aliases
Sometimes, you may want the container to resolve to a subclass when it encounters a particular typehint. In the example below, a new instance of D
will be injected into A
, instead of an instance of B
.
class D extends B { // placeholder class } $container->bindClassToAlias( B::class, D::class ); $a = $container->getObject('GiveMeANewA'); $d = $a->getB(); // $d is an instance of D