此外/无障碍/容器和服务/将服务添加到软件容器

将服务添加到容器中

在描述HLEB2框架的容器部分中,此文档已经提供了一个添加演示服务的简单示例。 接下来,我们将着眼于将一个真实的互斥锁库作为服务添加的示例。

github.com/phphleb/conductor包含互斥锁机制。如果您计划使用此库,则需要先安装它。

可以将容器中的键指定为库中的类,但以后这可能会导致问题,因为应用程序的代码将与特定类或库接口绑定,无法替换。

将外部库连接到项目最好使用适配器模式,其类将作为容器中的服务键。

<?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);
    }
}

此服务的包装类创建在/app/Bootstrap/Services/文件夹中。 尽管这对于示例来说是一个方便的目录,但从结构上讲,服务文件夹应位于项目逻辑旁边。

现在通过创建的类将库添加到容器中:

<?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();

        
// ... //
    
}
}

从示例中可以看到,rollback()方法被添加以重置支持异步的互斥锁库的状态。

添加后,新服务可以通过此类以singleton的方式从容器中获取。

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

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

在控制器、命令和事件中(在所有继承自Hleb\Base\Container的类中)使用新增服务的方法:

use App\Bootstrap\Services\MutexService;

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

您可以通过在App\Bootstrap\BaseContainer类及其接口中添加一个同名方法mutex()来简化服务调用:

use App\Bootstrap\Services\MutexService;

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

现在调用将如下:

$mutex $this->container->mutex();
页面翻译:chatgpt 4-o
返回顶部