lagdo/symfony-facades

使用门面调用 Symfony 服务。

v2.3.0 2024-09-21 03:34 UTC

This package is auto-updated.

Last update: 2024-09-21 03:42:52 UTC


README

Build Status Scrutinizer Code Quality StyleCI codecov

Latest Stable Version Total Downloads License

Symfony 服务的门面

使用此包,可以采用静态方法语法通过门面调用 Symfony 服务。

它是一个更简单的替代方案,用于在其他类的构造函数中传递服务作为参数,或使用懒加载服务。当类依赖于许多服务,但只偶尔调用其中一些时,它将特别有趣。

安装

使用 composer 安装此包。

composer require lagdo/symfony-facades

config/bundles.php 文件中注册 Lagdo\Symfony\Facades\FacadesBundle 包。

用法

门面继承自 Lagdo\Symfony\Facades\AbstractFacade 抽象类,并实现了 getServiceIdentifier() 方法,该方法必须返回 Symfony 服务容器中对应服务的 ID。

namespace App\Facades;

use App\Services\MyService;
use Lagdo\Symfony\Facades\AbstractFacade;

class MyFacade extends AbstractFacade
{
    /**
     * @inheritDoc
     */
    protected static function getServiceIdentifier()
    {
        return MyService::class;
    }
}

现在可以使用 App\Facades\MyFacade 门面调用 App\Services\MyService 服务的所有方法,如下所示。

class TheService
{
    public function theMethod()
    {
        MyFacade::myMethod();
    }
}

而不是这样。

class TheService
{
    /**
     * @var MyService
     */
    protected $myService;

    public function __construct(MyService $myService)
    {
        $this->myService = $myService;
    }

    public function theMethod()
    {
        $this->myService->myMethod();
    }
}

使用服务定位器

上述门面只能用于已声明为公开的服务。

为了使用门面调用私有服务,必须在 config/services.yaml 文件中声明具有 ID lagdo.facades.service_locator 的服务定位器。请参阅 Symfony 服务定位器文档

需要使用门面访问的私有服务必须作为参数传递给服务定位器。对于每个参数,键是门面中的服务 ID,值是容器中的服务 ID。

在以下示例中,将 Twig 服务传递给服务定位器。

    lagdo.facades.service_locator:
        public: true
        class: Symfony\Component\DependencyInjection\ServiceLocator
        tags: ['container.service_locator']
        arguments:
            -
                Twig\Environment: '@twig'

然后可以为 Twig 服务定义一个门面。

namespace App\Facades;

use Lagdo\Symfony\Facades\AbstractFacade;

class View extends AbstractFacade
{
    /**
     * @inheritdoc
     */
    protected static function getServiceIdentifier()
    {
        return \Twig\Environment::class;
    }
}

现在可以使用门面渲染模板。

use App\Facades\View;

class TheService
{
    public function theMethod()
    {
        ...
        $html = View::render($template, $vars);
        ...
    }
}

lagdo.facades.service 标签

从版本 2.3.0 开始,需要使用门面访问的私有服务可以标记为 lagdo.facades.service

这些服务将与作为参数接收的服务一起自动传递给服务定位器。

在以下示例中,将 App\Services\TaggedService 服务传递给服务定位器。

    lagdo.facades.service_locator:
        public: true
        class: Symfony\Component\DependencyInjection\ServiceLocator
        tags: ['container.service_locator']
        arguments:
            -
                Twig\Environment: '@twig'

    App\Services\TaggedService:
        tags: [lagdo.facades.service]
        class: App\Services\TaggedService

然后可以为该服务定义一个门面。

namespace App\Facades;

use App\Services\TaggedService;
use Lagdo\Symfony\Facades\AbstractFacade;

class TaggedServiceFacade extends AbstractFacade
{
    /**
     * @inheritdoc
     */
    protected static function getServiceIdentifier()
    {
        return TaggedService::class;
    }
}

获取服务实例

从版本 2.0.0 开始,instance() 方法返回服务的实例。

class TheService
{
    public function theMethod()
    {
        /**
         * @var MyService $service
         */
        $service = MyFacade::instance();
        $service->myMethod();
    }
}

ServiceInstance 特性

默认情况下,每次调用门面方法都会调用 Symfony 服务容器。

从版本 2.2.0 开始,可以使用 ServiceInstance 特性在第一次调用 Symfony 服务容器后将服务实例保存到门面中。下一次调用将返回服务实例而无需再次调用 Symfony 服务容器。

namespace App\Facades;

use App\Services\MyService;
use Lagdo\Symfony\Facades\AbstractFacade;
use Lagdo\Symfony\Facades\ServiceInstance;

class MyFacade extends AbstractFacade
{
    use ServiceInstance;

    /**
     * @inheritDoc
     */
    protected static function getServiceIdentifier()
    {
        return MyService::class;
    }
}

在此示例代码中,只调用一次 Symfony 服务容器。

    MyFacade::myMethod1(); // Calls the Symfony service container
    MyFacade::myMethod2(); // Doesn't call the Symfony service container
    MyFacade::myMethod1(); // Doesn't call the Symfony service container

提供的门面

此包包括一些 Symfony 服务的门面。

记录器

必须在 config/services.yaml 文件中将 logger 服务传递给服务定位器。

    lagdo.facades.service_locator:
        public: true
        class: Symfony\Component\DependencyInjection\ServiceLocator
        tags: ['container.service_locator']
        arguments:
            -
                Psr\Log\LoggerInterface: '@logger'

现在可以使用门面记录消息。

use Lagdo\Symfony\Facades\Log;

Log::info($message, $vars);

视图

必须在 config/services.yaml 文件中将 twig 服务传递给服务定位器。

    lagdo.facades.service_locator:
        public: true
        class: Symfony\Component\DependencyInjection\ServiceLocator
        tags: ['container.service_locator']
        arguments:
            -
                Twig\Environment: '@twig'

现在可以使用门面渲染视图。

use Lagdo\Symfony\Facades\View;

$html = View::render($template, $vars);

贡献

  • 问题跟踪器:github.com/lagdo/symfony-facades/issues
  • 源代码:github.com/lagdo/symfony-facades

许可

此包遵循 3-Clause BSD 许可协议。