Giter VIP home page Giter VIP logo

container's Introduction

Container

Container

Latest Version on Packagist Software License Total Downloads Coverage Status Quality Score Type coverage PHP Unit Say Thanks

Container implementation which follow PSR-11.

Requirements

PHP VERSION Container Version
8.0 < <= 1.6 1.0
>= 8.0 >= 1.7 1.0
>= 8.0 >= 1.8 2.0

Installation

composer require gravatalonga/container

Usage

Basic Usage

use Gravatalonga\Container\Container;

$container = new Container();
$container->set('random', function() {
    return rand(0, 1000);
});

$container->share('uniqueSeed', function() {
    return rand(0, 1000);
});

// create alias 'sessionId'  
$container->alias('uniqueSeed', 'sessionId');

echo $container->get('random'); // get random number each time you call this.

if ($container->has('uniqueSeed'))  {
    echo $container->get('uniqueSeed'); // get same random number.  
}

When creating a new instance of Container, you can pass on first argument configurations or entries to be already bonded into container.

use Gravatalonga\Container\Container;

new Container([
    'settings' => ['my-settings'], 
    FooBar::class => function (\Psr\Container\ContainerInterface $c) { 
        return new FooBar();
    }
]);

Using Service Provider

use Gravatalonga\Container\Container;


$container = new Container();
$container->set(RedisClass::class, function () {
    return new RedisClass();
});

// then you can use...
$cache = $container->get('Cache');

When using set, factory or share with Closure and if you want to get Container it's self, you can pass type hint of ContainerInterface as argument.

use Gravatalonga\Container\Container;
use Psr\Container\ContainerInterface;

$container = new Container([
    'server' => 'localhost',
    'username' => 'root'
]);

$container->set('Cache', function (ContainerInterface $container) {
    // some where you have binding this RedisClass into container... 
    return $container->make(RedisClass::class, [
        'server' => $container->get('server'), 
        'username' => $container->get('username')
    ]);
});

// set is a method alias of factory
$container->factory('CacheManager', function() {
    return new CacheManager();
});

// then you can use...
$cache = $container->get('Cache');

Using Array like access

use Gravatalonga\Container\Container;

$container = new Container();  
$container[FooBar::class] = function(ContainerInterface $container) {
    return new FooBar($container->get('settings'));
};

if (isset($container[FooBar::class])) {
    echo $container[FooBar::class]->helloWorld();
}

Alias

Alias like the name show, it to make a possibility to make an alias from one entry to another. It will throw an exception if can't be found.

use Gravatalonga\Container\Container;

$container = new Container();  
$container->set('settings', ['driver' => 'default']);
$container->set(FooBar::class, function($settings) {
    return new FooBar($settings);
});

$container->alias(FooBar::class, 'foo.bar');

$foobar = $container->get('foo.bar');

Callable as alternative

use Gravatalonga\Container\Container;

$class = new class
{
    public function get(): int
    {
        return mt_rand(0, 100);
    }
};

$container = new Container();  
$container->factory('random', [$class, 'get']);

$foobar = $container->get('random'); // it will get random int

Extend

In order implementation to be ease for other services providers extend method was created.

use Gravatalonga\Container\Container;

class Test
{
    /**
     * @var string
     */
    public $name;

    public function __construct($name = 'Jonathan Fontes')
    {
        $this->name = $name;
    }
}

$container = new Container(); 

$container->get(Test::class, function(ContainerInterface $container) {
    return new Test;
});

$container->extend(Test::class, function(ContainerInterface $container, $test) {
    return new Test($test->name.' - The greatest!');
});

echo $container->get(Test::class); // It will print 'Jonathan Fontes - The greatest!';  

Advance usage

Container is capable to resolve class who isn't bounded, it will resolve dependencies from __construct type-hint/built-in which is bounded. Read example code below:

Information: built-in is type which is built in on PHP, which is string, int, boolean, etc. Type Hint is type which is created by user land, such as, when creating a class you are creating a new type.

Using Type Hint Class

use Gravatalonga\Container\Container;

class FooBar {}

class Test
{
    public function __construct(FooBar $foobar)
    {
        $this->foobar = $foobar;
    }
}

$container = new Container(); 
$container->set(FooBar::class, function () {
    return new FooBar();
});

$container->get(Test::class); // FooBar it will inject into Test class.  

Note: We only support resolving auto wiring argument on construction if they are bounded into container. Otherwise it will throw an exception if can't find entry.

Using Built in type

use Gravatalonga\Container\Container;
class Test
{
    public function __construct(string $name)
    {
        $this->name = $name;
    }
}

$container = new Container(); 
$container->set('name', 'my-var');

$container->get(Test::class); // my-var it will inject into Test class.  

If argument accept nullable if can't be resolve it will pass default value which in this case is null.

use Gravatalonga\Container\Container;

class Test
{
    /**
     * @var string
     */
    private $name;

    public function __construct(string $name = null)
    {
        $this->name = $name;
    }
}

$container = new Container(); 

$container->get(Test::class); // null it will inject into Test class.  

In also attempt to resolve auto wiring of construction by its default value, it will check default value of __construct and it will pass that default value.

First case, if value is a simple built-in type value.

use Gravatalonga\Container\Container;

class Test
{
    /**
     * @var string
     */
    private $name;

    public function __construct($name = 'Jonathan Fontes')
    {
        $this->name = $name;
    }
}

$container = new Container(); 

$container->get(Test::class); // 'Jonathan Fontes' it will pass into container...

Tip

It's well-known that using singleton pattern, it's an anti-pattern. But small feature can't hurt you

So, you can use:


$container = new Container();

// ... 

Container::setInstance($container);

Then you can get instance of container,

$container = Container::getInstance();

Tips: The container can detected circular dependencies.

Change log

Please see CHANGELOG for more information on what has changed recently.

Testing

composer grumphp

Contributing

Please see CONTRIBUTING and CODE_OF_CONDUCT for details.

Security

If you discover any security related issues, please email jonathan.alexey16[at]gmail.com instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.

container's People

Contributors

drupol avatar gravatalonga avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

chris6578

container's Issues

new Extend method - Add new method to extended already binded entry of container

Detailed description

This new method is in order to make ease to extend already binded entry of container. In order to extend method i'm predicted that the second argument must be $previous which hold the resolved entry of set, factory and share (which not yet be resolved). This new method would be compatibility with this project: https://github.com/container-interop/service-provider

Screenshot 2020-05-11 at 14 18 44

What you think? @drupol

PSR-11 ContainerInterface 2.0.0

Detailed description

Upgrade from ContainerInterface:1.0.0 to ContainerInterface:2.0.0 and bump minor version. But exists conflit directly to grumphp maybe we need to leave out this library.

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.