2017-25 © Pedro Peláez
 

library container

Dependency injection container.

image

weew/container

Dependency injection container.

  • Thursday, July 21, 2016
  • by weew
  • Repository
  • 1 Watchers
  • 1 Stars
  • 186 Installations
  • PHP
  • 8 Dependents
  • 0 Suggesters
  • 0 Forks
  • 0 Open issues
  • 20 Versions
  • 0 % Grown

The README.md

Dependency injection container

Build Status Code Quality Test Coverage Version Licence, (*1)

Table of contents

Installation

composer require weew/container, (*2)

Creating a container

The container has no additional dependencies, so a simple instantiation will do the trick., (*3)

$container = new Container();

Primitive data

Storing any type of data:, (*4)

$container->set('foo', 'bar');

// returns bar
$container->get('foo');

Classes

Retrieving classes:, (*5)

class Foo {}

// returns a new instance of Foo
$container->get(Foo::class);

Passing additional parameters:, (*6)

class Foo {
    public function __construct($x, $y = 2) {};
}

// parameters are matched by name
$container->get(Foo::class, ['x' => 1]);

Resolving constructor dependencies:, (*7)

class Foo {
    public function __construct(Bar $bar) {}
}
class Bar {}

// returns a new instance of Foo,
// Foo's constructor receives a new instance of Bar
$container->get(Foo::class);

Sharing a specific instance:, (*8)

class Foo {}

$container->set(Foo::class, new Foo());
// or
$container->set(new Foo());

// everyone will get the same instance of Foo
$container->get(Foo::class);

Factories

Working with factories:, (*9)

class Foo {
    public $bar;
}
class Bar {}

// a factory method will get it's dependencies resolved too.
$container->set(Foo::class, function(Bar $bar) {
    $foo = new Foo();
    $foo->bar = $bar;

    return $foo;
});

Accessing container from within a factory:, (*10)

$container->set('foo', 1);

// a container can be injected the same way as any other dependency
$container->set('bar', function(IContainer $container) {
    return $container->get('foo');
));

Container is not limited to closure factories, it supports class method and static method factories too:, (*11)

class MyFactoryClass {
    public function factoryMethod(AnotherDependency $dependency) {}
    public function staticFactoryMethod(AnotherDependency $dependency) {}
}

$container->set(Foo::class, new MyFactoryClass(), 'factoryMethod');
$container->set(Foo::class, MyFactoryClass::class, 'factoryMethod');
$container->set(Foo::class, MyFactoryClass::class, 'staticFactoryMethod');

Traditional callable array syntax is also supported. It does exactly the same as the examples above, but with a slightly different syntax:, (*12)

$container->set(Foo::class, [new MyFactoryClass(), 'factoryMethod']);
$container->set(Foo::class, [MyFactoryClass::class, 'factoryMethod']);
$container->set(Foo::class, [MyFactoryClass::class, 'staticFactoryMethod']);

All facotires benefit from dependency injection. Additionaly, if you let the container instantiate your factory, it will be resolved trough the container too., (*13)

Interfaces

Resolving interfaces:, (*14)

interface IFoo {}
class Foo implements IFoo {}

$container->set(IFoo::class, Foo::class);

// will return an instance of Foo
$container->get(IFoo::class);

Sharing specific interface implementation:, (*15)

interface IFoo {}
class Foo implements IFoo {}

$container->set(IFoo::class, new Foo());

// everyone will get the same instance of Foo
$container->get(IFoo::class);

Interfaces can have factories too:, (*16)

interface IFoo {}
class Foo implements IFoo {}

$container->set(IFoo::class, function() {
    return new Foo();
});

// will return a new instance of Foo
$container->get(IFoo::class);

Of course you can also type hint interfaces:, (*17)

interface IFoo {}
class Foo implements IFoo {}
class Bar {
    public function __construct(IFoo $foo) {}
}

$container->set(IFoo::class, Foo::class);

// returns an instance of Bar
// Bar receives an instance of Foo, which implements the interface IFoo
$container->get(Bar::class);

Functions and methods

Functions can get resolved by the container:, (*18)

class Bar {}
function foo(Bar $bar, $foo) {}

// method foo gets called and receives an instance of Bar
// as with the other container methods, you can always pass your own arguments
$container->callFunction('foo', ['foo' => 1]);

The same works for closures:, (*19)

class Bar {}

// closure gets called and receives an instance of Bar
$container->callFunction(function(Bar $bar) {});

Invoking class methods is also strait forward:, (*20)

class Foo {}
class Bar {
    public function takeFoo(Foo $foo, $x) {}
}

$bar = new Bar();
// method takeFoo gets invoked and receives a new instance
// of Foo, as well as the custom arguments
$container->callMethod($bar, 'takeFoo', ['x' => 1]);
// you could also let the container create an instance
$container->callMethod(Bar::class, 'takeFoo', ['x' => 1]);

Invoking static methods:, (*21)

class Foo {}
class Bar {
    public static function takeFoo(Foo $foo, $x) {}
}

// method takeFoo gets invoked and receives a new instance
// of Foo, as well as the custom arguments
$container->callStaticMethod(Bar::class, 'takeFoo', ['x' => 1]);

It is possible to use PHP's traditional callable syntax for invocation of functions and methods:, (*22)

// same as $container->callFunction($functionName, $args)
$container->call($functionName, $args);
// same as $container->callFunction($closure, $args)
$container->call($closure, $args);
// same as $container->callMethod($instance, $method, $args)
$container->call([$instance, $method], $args);
// same as $container->callMethod($className, $method, $args)
$container->call([$className, $method], $args);
// same as $container->callStaticMethod($className, $staticMethod, $args)
$container->call([$className, $staticMethod], $args);

Singletons

Container values can be defined as singletons. A singleton definition will return the same value over and over again. Here is an example of a singleton interface definition:, (*23)

interface IFoo {}
class Foo implements IFoo {}

$container->set(IFoo::class, Foo::class)->singleton();

The same works for classes:, (*24)

class Foo {}

$container->set(Foo::class)->singleton();

And factories:, (*25)

class Foo {}

$container->set(Foo::class, function() {
    return new Foo();
})->singleton();

Sharing an instance always results in a singleton:, (*26)

class Foo {}

$container->set(Foo::class, new Foo())->singleton();
// same as
$container->set(Foo::class, new Foo());

Wildcards

This one might be especially useful when working with factories. Lets take Doctrine for example. You can not simply instantiate a repository by yourself. But still, it would be great if you could have them resolved by the container. Unfortunately, this will throw an error, since the repository requires a special parameter that can and should not be resolved by the container:, (*27)

class MyRepository {
    public function __construct(SpecialUnresolvableValue $value) {}
}

$container->get(MyRepository::class);

However, you might use a wildcard factory. You can use any regex pattern as a mask. Right now, the only supported regex delimiters are / and #., (*28)

class MyRepository implements IRepository {
    public function __construct(SpecialUnresolvableValue $value) {}
}
class YoursRepository implements IRepository {
    public function __construct(SpecialUnresolvableValue $value) {}
}

$container->set('/Repository$/', function(RepositoryFactory $factory, $abstract) {
    return $factory->createRepository($abstract);
});

$container->get(MyRepository::class);
$container->get(YourRepository::class);

As you see here, the actual class name MyRepository was passed to the custom factory as the $abstract parameter. From there, we call the RepositoryFactory and tell it to create us a new instance of MyRepository. Afterwards the same factory can be used to create an instance of YourRepository., (*29)

Telling the container that all instances produced within this factory should be singletons is very simple:, (*30)

$container->set('/Repository$/', function(RepositoryFactory $factory, $abstract) {
    return $factory->createRepository($abstract);
})->singleton();

Wildcards are very powerful, however, they should be used with caution, since they could break your application if you configure them wrong. (for example: if the regex mask is not precise enough and matches unwanted classes). Thanks to regex, creating precise masks shouldn't be a big deal though., (*31)

Wildcards can also be used in combination of class names and instances. But I find the usecases for this very limited:, (*32)

$container->set('/Repository$/', EntityRepository::class);
$container->set('/Repository$/', $instance);

Aliases

If you need to create an alias for a definition, for example when you want to provide a factory for a class as well as for it's interface, and don't want to do it twice for each one, you could create a definition with an alias (or two, or ten). Just provide an array of identifiers. The first element in the array is considered as "the id" and the others are aliases., (*33)

$container->set([MyImplementation::class, IImplementation::class], function() {
    return new MyImplementation('foo');
});

// both calls will return a value from the same factory
$container->get(MyImplementation::class);
$container->get(IImplementation::class);

The same would work with singletons, primitive values and so on., (*34)

Additional methods

Check if the container has a value:, (*35)

$container->set('foo', 'bar');

// will return true
$container->has('foo');

Remove a value from the container:, (*36)

$container->set('foo', 'bar');
$container->remove('foo');

// will return false
$container->has('foo');

Extensions

There are additional extension available to make the container even more powerful., (*37)

Doctrine integration

The weew/container-doctrine-integration package makes doctrine repositories injectable., (*38)

The Versions

21/07 2016

dev-master

9999999-dev

Dependency injection container.

  Sources   Download

MIT

The Requires

 

The Development Requires

by Maxim Kott

21/07 2016

v1.2.1

1.2.1.0

Dependency injection container.

  Sources   Download

MIT

The Requires

 

The Development Requires

by Maxim Kott

08/03 2016

v1.2.0

1.2.0.0

Dependency injection container.

  Sources   Download

MIT

The Requires

  • weew/php-helpers-array ^1.0.0
  • weew/php-helpers-string ^1.0.0

 

The Development Requires

by Maxim Kott

02/03 2016

v1.1.0

1.1.0.0

Dependency injection container.

  Sources   Download

MIT

The Requires

  • weew/php-helpers-array ^1.0.0
  • weew/php-helpers-string ^1.0.0

 

The Development Requires

by Maxim Kott

20/11 2015

v1.0.1

1.0.1.0

Dependency injection container.

  Sources   Download

MIT

The Requires

  • weew/php-helpers-array ^1.0.0
  • weew/php-helpers-string ^1.0.0

 

The Development Requires

by Maxim Kott

16/11 2015

v1.0.0

1.0.0.0

Dependency injection container.

  Sources   Download

MIT

The Requires

  • weew/php-helpers-array ^1.0.0
  • weew/php-helpers-string ^1.0.0

 

The Development Requires

by Maxim Kott

16/09 2015

v0.1.12

0.1.12.0

Dependency injection container.

  Sources   Download

MIT

The Requires

  • weew/php-helpers-array 0.*
  • weew/php-helpers-string 0.*

 

The Development Requires

by Maxim Kott

16/09 2015

v0.1.11

0.1.11.0

Dependency injection container.

  Sources   Download

MIT

The Requires

  • weew/php-helpers-array 0.*
  • weew/php-helpers-string 0.*

 

The Development Requires

by Maxim Kott

16/09 2015

v0.1.10

0.1.10.0

Dependency injection container.

  Sources   Download

MIT

The Requires

  • weew/php-helpers-array 0.*
  • weew/php-helpers-string 0.*

 

The Development Requires

by Maxim Kott

16/09 2015

v0.1.9

0.1.9.0

Dependency injection container.

  Sources   Download

MIT

The Requires

  • weew/php-helpers-array 0.*
  • weew/php-helpers-string 0.*

 

The Development Requires

by Maxim Kott

15/09 2015

v0.1.8

0.1.8.0

Dependency injection container.

  Sources   Download

MIT

The Requires

  • weew/php-helpers-array 0.*
  • weew/php-helpers-string 0.*

 

The Development Requires

by Maxim Kott

12/09 2015

v0.1.7

0.1.7.0

Dependency injection container.

  Sources   Download

MIT

The Requires

  • weew/php-helpers-array 0.*
  • weew/php-helpers-string 0.*

 

The Development Requires

by Maxim Kott

10/09 2015

v0.1.6

0.1.6.0

Dependency injection container.

  Sources   Download

MIT

The Requires

  • weew/php-helpers-array 0.*
  • weew/php-helpers-string 0.*

 

The Development Requires

by Maxim Kott

10/09 2015

v0.1.5

0.1.5.0

Dependency injection container.

  Sources   Download

MIT

The Requires

  • weew/php-helpers-array 0.*
  • weew/php-helpers-string 0.*

 

The Development Requires

by Maxim Kott

07/09 2015

v0.1.4

0.1.4.0

Dependency injection container.

  Sources   Download

MIT

The Requires

  • weew/php-helpers-array 0.*
  • weew/php-helpers-string 0.*

 

The Development Requires

by Maxim Kott

07/09 2015

v0.1.3

0.1.3.0

Dependency injection container.

  Sources   Download

MIT

The Requires

  • weew/php-helpers-array 0.*
  • weew/php-helpers-string 0.*

 

The Development Requires

by Maxim Kott

07/09 2015

v0.1.2

0.1.2.0

Dependency injection container.

  Sources   Download

MIT

The Requires

  • weew/php-helpers-array 0.*
  • weew/php-helpers-string 0.*

 

The Development Requires

by Maxim Kott

07/09 2015

v0.1.1

0.1.1.0

Dependency injection container.

  Sources   Download

MIT

The Requires

  • weew/php-helpers-array 0.*
  • weew/php-helpers-string 0.*

 

The Development Requires

by Maxim Kott

03/09 2015

v0.0.2

0.0.2.0

Dependency injection container.

  Sources   Download

MIT

The Development Requires

by Maxim Kott

02/09 2015

v0.0.1

0.0.1.0

Dependency injection container.

  Sources   Download

MIT

The Development Requires

by Maxim Kott