Additionally/Accessibility/Container and services/Adding a service to a container

Adding a Service to the Container

In the section describing the Container for the HLEB2 framework, this documentation already provides a simple example of adding a demo service. Next, we'll look at an example of adding a real library for mutexes as a Service.

The library github.com/phphleb/conductor contains a mutex mechanism. If you plan to use this library, you need to install it first.

It is perfectly possible to assign a key in the container as a class from the library, but this may cause issues later as the application's code will be tied to a specific class or library interface, making it impossible to change it.

It is better to connect external libraries to the project using the Adapter pattern, the class of which will be the key of the service in the container.

<?php
// File /app/Bootstrap/Services/MutexService.php

namespace App\Bootstrap\Services;

use 
Phphleb\Conductor\Src\Scheme\MutexInterface;

class 
MutexService
{
    public function 
__construct(private MutexInterface $mutex) { }

    public function 
acquire(string $name, ?int $sec null): bool
    
{
        return 
$this->mutex->acquire($name$sec);
    }

    public function 
release(string $name): bool
    
{
        return 
$this->mutex->release($name);
    }

    public function 
unlock(string $name): bool
    
{
        return 
$this->mutex->unlock($name);
    }
}

This wrapper class for the service is created in the /app/Bootstrap/Services/ folder. Although this is a convenient directory for examples, structurally the Services folder should be located next to the project logic.

Now let's add the library to the container by the created class:

<?php
// File /app/Bootstrap/ContainerFactory.php

namespace App\Bootstrap;

use 
App\Bootstrap\Services\MutexService;
use 
Hleb\Constructor\Containers\BaseContainerFactory;
use 
Phphleb\Conductor\FileMutex;
use 
Phphleb\Conductor\Src\MutexDirector;

final class 
ContainerFactory extends BaseContainerFactory
{
    public static function 
getSingleton(string $id): mixed
    
{
        
self::has($id) or self::$singletons[$id] = match ($id) {
            
// New service as singleton.
            
MutexService::class => new MutexService(new FileMutex()),

            
// ... //
            
default => null
        
};
        return 
self::$singletons[$id];
    }

    public static function 
rollback(): void
    
{
        
// Rollback for an asynchronous request.
        
MutexDirector::rollback();

        
// ... //
    
}
}

As seen in the example, the rollback() method has been added to reset the state for the connected mutex library that supports asynchrony.

After adding, the new service is available from the container as a singleton through this class.

use App\Bootstrap\Services\MutexService;
use 
Hleb\Static\Container;

$mutex Container::get(MutexService::class);

The method of using the added service in controllers, commands, and events (in all classes inherited from Hleb\Base\Container):

use App\Bootstrap\Services\MutexService;

$mutex $this->container->get(MutexService::class);

You can simplify the example call to the service by adding a new method with the same name mutex() to the App\Bootstrap\BaseContainer class and its interface:

use App\Bootstrap\Services\MutexService;

#[\Override]
final public function 
mutex(): MutexService
{
    return 
$this->get(MutexService::class);
}

Now the call will look like this:

$mutex $this->container->mutex();
Page translated: chatgpt 4-o
Back to top