Paint the Web - a micro-Blog in .md about Dev, Web and more

Flood Component: Container

A container is an object that stores the construction or execution of different other logic parts. The saved callable is then registered with an id and could be accessed everywhere.

There are two basic registering methods:

  • 1 Singleton Style
    • there is one instance of an object assigned to one id
    • every request for that id returns the same object
  • 2 Callback Style
    • there is a anonymous function (for example)
    • in this the object is created and returned at last
    • the anonymous function is executed everytime the id is requested
    • todo: add reflection DI and array based params

Basic Use Case

The container component is the basic service for building a container service. It implements the basic interface, that is extended from the PSR container interface.

The main class implements methods for registering, overwriting and requesting objects.

That main class is (never) initiated directly, it is used by other flood/* parts, like Hydro or FloodComponent: PerformanceMonitor, for implementing their own but interoperable container. With this all containers could also be updated easily and new (sub)containers are build in seconds.

The main class:
component-container/src/Container.php
The interface:
component-container/src/iContainer.php

Exception wrapper:
component-container/src/Exception.php
component-container/src/NotFoundException.php

The methods Container.get($id) and Container.register($id) are the basic accessor/setter.

Other flood part's containers mostly just implement convenience methods, those wrap a get() and provide native IDE auto-complete support. Those begin (unlike any other methods) with a single underscore, e.g. _config() for get('config'). That notation was choosen to have a fast access to any object with as little effort as possible.

Access

The container is the class Flood\Component\Container\Container which has the singleton method i() and an empty ::$container_id.

<?php
use Flood\Component\Container\Container;

Container::i()->register('some-id', new \SomeClass()); // Style 1
Container::i()->register('b-id', function () {
    return new \AnotherClass();
}); // Style 2

Container::i()->get('some-id')->thatMethod(); // executes \SomeClass->thatMethod()  
$var = Container::i()->get('b-id'); // sets the var to a new instance of \AnotherClass

Methods

  • Container

    • ::i() - returns the container class, self or the overwritten object
    • ::overwriteContainer($callback) - overwrites $i, see above
    • destroy() - destructor for resetting $i
    • get($id) - returns the executed callback for that id, or the value
    • register($id, $object) - registers the callback for that id, or the value
    • &bind($id, &$reference = null, $overwrite = false) - gets or sets a bind
    • overwrite($id, $object) - overwrites the callback for that id
    • isOverwritten($id) - if the id is overwritten already
    • has($id) - if the id exists and its callable is not empty
  • Convenience Methods:
    • in FloodComponent: Route
      • _hook() - for get('hook')
      • _hookStorage() - for get('hook-storage')
      • _hookRouteGenerator() - for get('hook-route-generator')
      • _cache() - for get('cache')
    • in Hydro

Debug

Just set Container::$debug to true and exception messages will be printed instead of logged to your error log.

Build (Sub)Container

To build your own container, you just add a little bit of code to your class.

A note on the scope and why some must be declared in subclass:

With adding $i to ModContainer, the static:: scope is set correctly, e.g. the scope of static::$i in the parent class is ModContainer::$i and not \Flood\Component\Container\Container::$i.

In contrary $this->container_id doesn't need to be set as it is not a static property and will be created with each new container instance.

<?php
namespace MyApp\Library;

class ModContainer extends \Flood\Component\Container\Container {

    protected static $i = null;

    protected function __construct() {
        parent::__construct();
        // must be unique among all containers
        // recommended is an abstraction of the namespace and class name 
        $this->container_id = 'MyAppLibraryContainer';
    }

    /**
     * Returns an instance of this class, just added for native IDE auto-complete support
     *
     * @return self
     */
    public static function i() {
        return parent::i();
    }
}

Overwrite & Bind

So you just scrolled over the text and didn't found the links in methods?

Just go to Container: overwrite + bind.