Coder Social home page Coder Social logo

sasa-b / container Goto Github PK

View Code? Open in Web Editor NEW
1.0 1.0 1.0 57 KB

Lightweight dependency injection container with laravel like autowiring, interface/abstract class binding and contextual binding. PSR-11 compliant.

License: MIT License

PHP 100.00%
ioc dependency dependency-injection php library container dependency-injection-container ioc-container

container's Introduction

IOC container

Lightweight dependency injection container with laravel like autowiring, interface/abstract class binding and contextual binding. PSR-11 compliant.


To use the library clone the repo or just use composer to install it.

composer require sasa-b/container

Usage examples

require '../vendor/autoload.php';

$container = new Foundation\Container\Container();`

Binding/Registering services

A service (bound value) can be a string representation of a class, an anonymous function which returns an object instance, or an object instance itself. If you bind an object instance itself, that service will essentially act as a singleton because the same instance will always be returned.

$container->bind(Foo\Bar::class, Foo\Bar::class); 

$container->bind(Foo\Bar::class, function ($container) { 
   return new \Foo\Bar($container['Foo\Baz']);
   
}); 

$container->bind('Foo\Bar', FooBar::class); 

$container->bind(Foo\Bar::class, new \Foo\Bar());
Singletons
   $container->bind('Foo\Bar', FooBar::class)->share();
   
   //or
   
   $container->bind('Foo\Bar', FooBar::class);
   $container->share(Foo\Bar::class);
   
   $container->bind(Foo\Baz::class, Foo\Baz::class)->mapTo('baz');
   $container->share('baz');

Mapping services to keys

For convenience you can map your services to keys and there are multiple ways of doing it.

  1. With mapTo method via method chaining
$container->bind(Foo\Bar::class, Foo\Bar::class)->mapTo('foo');
  1. With the key method
$container->key('foo', Foo\Bar::class);
  1. Directly with the bind statement
$container->bind('foo', function ($container) {
   return new Foo\Bar();
});

When you directly bind services to a key, they will only be accessible by that key and those services can't be used for autowiring (injecting by type hinting), unless the service you are binding/registering is a string representaton of a class, in that case the service will automatically be mapped to the given key.

In case of mapTo and key bound/registered services are accessible by both the key and their class name, and because of that they can be used for autowiring.

Binding/Registering multiple services

For registering multiple services at once you can use the register method or it's alias bindMany.

$container->register([
    Foundation\Request\Http::class => Foundation\Request\Http::class,
    Foundation\Sessions\SessionManager::class => \Foundation\Sessions\SessionManager::class,
    Foundation\Request\Cookie::class => Foundation\Request\Cookie::class,
    'date' => \DateTime::class,
    Foundation\Core\Database::class => Foundation\Core\Database::class,
    Foundation\Database\QueryBuilder::class => (function ($c) {
        return new \Foundation\Database\PDOQuery($c['db']);
    })
])->mapTo(['request', 'session', 'cookie', 'db']);

$container->register([
    Foundation\Request\Http::class => Foundation\Request\Http::class,
    Foundation\Sessions\SessionManager::class => \Foundation\Sessions\SessionManager::class,
    Foundation\Request\Cookie::class => Foundation\Request\Cookie::class
]);

$container->keys([
   'request' => Foundation\Request\Http::class,
   'session' => Foundation\Sessions\SessionManager::class,
   'cookie' => Foundation\Request\Cookie::class
]);
Registering multiple singletons
/* Only those specified will be registered as singletons */
$container->register([
    Foundation\Request\Http::class => Foundation\Request\Http::class,
    Foundation\Sessions\SessionManager::class => \Foundation\Sessions\SessionManager::class,
    Foundation\Request\Cookie::class => Foundation\Request\Cookie::class,
    'date' => \DateTime::class,
    Foundation\Core\Database::class => Foundation\Core\Database::class,
    Foundation\Database\QueryBuilder::class => (function ($c) {
        return new \Foundation\Database\PDOQuery($c['db']);
    })
])->share(['session', 'db', Foundation\Core\Database::class]);

/* All will be registered as singletons */
$container->register([
    Foundation\Request\Http::class => Foundation\Request\Http::class,
    Foundation\Sessions\SessionManager::class => \Foundation\Sessions\SessionManager::class,
    Foundation\Request\Cookie::class => Foundation\Request\Cookie::class,
    'date' => \DateTime::class,
    Foundation\Core\Database::class => Foundation\Core\Database::class,
    Foundation\Database\QueryBuilder::class => (function ($c) {
        return new \Foundation\Database\PDOQuery($c['db']);
    })
])->share();
// or
$container->register([
    Foundation\Request\Http::class => Foundation\Request\Http::class,
    Foundation\Sessions\SessionManager::class => \Foundation\Sessions\SessionManager::class,
    Foundation\Request\Cookie::class => Foundation\Request\Cookie::class,
    'date' => \DateTime::class,
    Foundation\Core\Database::class => Foundation\Core\Database::class,
    Foundation\Database\QueryBuilder::class => (function ($c) {
        return new \Foundation\Database\PDOQuery($c['db']);
    })
], true);

Abstract binding

You can bind/register services to interfaces and abstract classes as well. These abstract bindings are convenient when used with autowiring, because you can type hint with abstractions (abstract classes and interfaces) and not concretions (implementations).

$container->bind(Foo\BarInterface::class, Foo\Bar::class);
$container->bind(Foo\AbstractBaz::class, Foo\Baz::class);
Contextual binding

When you want to bind/register multiple different services to a same interface or abstract class you need to provide context otherwise one will override the other. Context is the third parameter to the bind method, and it can be a string representation of a class or a key mapped to a class, and that class needs to be the one in whose constructor or method the interface/abstract class is used as a typehint.

// This will result in an override and `Foo\Baz::class` will always be returned for Foo\Bar::interface
$container->bind(Foo\BarInterface::class, Foo\Bar::class);
$container->bind(Foo\BarInterface::class, Foo\Baz::class);

$container->bind(Foo\BarInterface::class, Foo\Bar::class);
$container->bind(Foo\BarInterface::class, Foo\Baz::class, 'FooController');

Retrieveing services

$service = $container['Foo\Bar'];
$service = $container[Foo\Bar::class];
$service = $container['foo'];

// Only works for services mapped to keys
$service = $container->foo();
$service = $container->foo;

// Retrieves a new instance or a singleton if a service has been registered as a singleton
$service = $container->get('foo');

// Always retrieves a singleton
$service = $container->shared('foo');

container's People

Contributors

sasa-b avatar

Stargazers

 avatar

Watchers

 avatar

Forkers

ksmore

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.