ClanCats Logo

Container

Basic Container usage

As already stated and in the Getting started guide, there are multiple ways to construct an instnace of the service container. But in the end it does not really matter if a container is generated using the factory or is created dynamically, the usage / API of the container instance is the same for all of them.


 Construction and Parameters

The constructor of the container always accepts an inital array of dynamic parameters.

use ClanCats\Container\Container;
$container = Container(['env' => 'production']);

This also works if you construct the container instance using a factory:

$factory = new \ClanCats\Container\ContainerFactory(__DIR__ . '/cache');
$container = $factory->create('AppContainer', function($builder) {}, ['env' => 'production']);

The given inital parameters will be merged with already defined parameters.


Reading a parameter

This method really does not require to explain alot, thats why im wasting your time with this sentence.

$container->getParameter('env');

You can get a parameter with a fallback value. The fallback value will be returned if the parameter has not been defined. If the parameter is null the default value won't be returned.

$container->getParameter('cron.idle.timeout', 3600);

Get the parameter with the the given name, or return the default value if the parameter is not set.

Method definition:

public function getParameter(string $name, $default = null)

Arguments

Data type Variable name Comment
string $name The parameter name.
mixed $default The returned default value if the parameter is not set.

Returns

mixed


Setting a parameter

I like to think of parameters as configuration values that are more or less scalar, but there is no limitation on what a parameter can be. You could assign objects as parameters but that does not mean you should.

$container->setParameter('session.cookie.name', 'mysessiontoken');
$container->setParameter('available.languages', ['de', 'en', 'it', 'fr']);

Set the given parameter with value

Method definition:

public function setParameter(string $name, $value)

Arguments

Data type Variable name Comment
string $name The parameter name.
mixed $value The parameter value.

Returns

void


Check if parameter exists

Sometimes you just need to know if a parameter exists. If a parameter is null it still exists!

Does the container contain the parameter with the given name?

Method definition:

public function hasParameter(string $name) : bool

Arguments

Data type Variable name Comment
string $name The parameter name.

Returns

bool


 Getting services / status


Getting a service

Gets the service with the given name from the container. This method will also construct the service if it has not been requested before or is of type prototype.

$container->get('repository.comment');

The name container is the only reserved one, and will always refer to the container itself;

$container->get('container'); // === $container

If a service does not exist the container will throw an UnknownServiceException if it is requested. So you should either catch the exeption or check if the servie exists beforehand if you don't trust your dependency tree.

if ($container->has('not.sure.if.exists')) {
    $container->get('not.sure.if.exists'); // do something with it
}
try {
    $container->get('not.sure.if.exists');
} catch(ClanCats\Container\Exceptions\UnknownServiceException $e) {
    // do something its not there.
}

Retrieve a service from the container.

Method definition:

public function get(string $serviceName)

Arguments

Data type Variable name Comment
string $serviceName The name / Identifier of the service to look for.

Returns

mixed The requested service.


Available services

Working on debugging tools and just need to know what services would be available?

echo implode(', ', $container->available());

Returns an array of all available service keys.

Method definition:

public function available() : array

Returns

array[string]


Has service

Does the container have the given service?

Method definition:

public function has(string $serviceName) : bool

Arguments

Data type Variable name Comment
string $serviceName The name / Identifier of the service to look for.

Returns

bool


Is service resolved

If you need to know if a service has already been loaded / requested / resolved you can make use of the isResolved method. This is also mainly usefull for profiling and debugging.

foreach($container->available() as $serviceKey) {
    echo "@{$serviceKey}: " . ($conatiner->isResolved(serviceKey) ? 'yes' : 'no') . PHP_EOL;
}

Check if the given service has already been resolved / shared / initiated. A factory service will always return false.

Method definition:

public function isResolved(string $serviceName) : bool

Arguments

Data type Variable name Comment
string $serviceName The name / Identifier of the service to look for.

Returns

bool


 Binding / Setting Services

You can bind new services to the container at any given time. Again this does not depend on how you build / construct your container instance. You can mix dynamic services binding with compiled ones. There is no technical pittfall doing so but for sake of consistency I would stick with one way.


Bind service

Autogenerate & return the service factory:

$contanier->bind('enterprise', SpaceShip::class)
    ->arguments(['USS Enterprise']);

When the service factory is autogenerated the bind method will return the factory object. This is why we can call the arguments method right after binding. This is the only case where the bind method returns something.

Pass a service factory as argument:

$contanier->bind('enterprise', new ServiceFactory('\\SpaceShip', ['USS Enterprise']));

In this case the bind method won't return the ServiceFactory object because it is already under your control. Note that we pass the service arguments directly to the service factory.

Note: If the arguments confuse you read: Service Arguments

Using a closure:

$contanier->bind('enterprise', function($c) 
{
    return new SpaceShip('USS Enterprise');
});

Note: This page is just a short usage guide for detailed documentation read Service Binding

Binds a service factory to the container.

$container->bind('session', new SessionFactory);
$container->bind('config', function($c) {
     return new Config($c->get('config.loader'));
}, false);
$container->bind('router', '\\Routing\\Router')
    ->addDependencyArgument('config');

Method definition:

public function bind(string $name, $factory, bool $shared = true)

Arguments

Data type Variable name Comment
string $name The service name.
mixed $factory The service factory instance, the closure or the classname as string
bool $shared Should the service be shared inside the container.

Returns

Closure, ServiceFactoryInterface The given or generated service factory.


Set service

There probably will come the day where you need to simply inject something into container, for this purpose we have the set method.

$objectISomehowNeedToCreateHere = new Thing();

$contanier->set('thing', $objectISomehowNeedToCreateHere);

Sets a value on the container instance. This will overwrite any service stored / shared under the same name.

Method definition:

public function set(string $serviceName, $serviceValue)

Arguments

Data type Variable name Comment
string $serviceName The name / Identifier of the service to look for.
mixed $serviceValue

Returns

void


Releasing / Removing services


Release service

This method will remove the in the container stored instance of the service. But if I understand PHP right every object is kind of a shared pointer. Means as long as you store a reference to the resolved object it won't get released. (Correct me if im wrong here.)

$container->release('db.connection');

Release a shared resolved service from the container. This will force the service to reload when accessed again.

Method definition:

public function release(string $serviceName) : bool

Arguments

Data type Variable name Comment
string $serviceName

Returns

bool Return false on failure.


Remove service

$container->remove('kernel'); // dangerous?

This will if possible release the resolevd instance and remove the service definition from the container.

Note: This will also work for compiled service definitions!

Removes a service from the container and releases the shared instance if it has been loaded.

Method definition:

public function remove(string $serviceName) : bool

Arguments

Data type Variable name Comment
string $serviceName The name / Identifier of the service to look for.

Returns

bool Returns true if the service has been removed.