lagdo / symfony-facades
使用门面调用 Symfony 服务。
Requires
- psr/container: >=1.0.0
- symfony/framework-bundle: 5.*|6.*|7.*
Requires (Dev)
- php: >=7.0.0
- nyholm/symfony-bundle-test: ^2.0
- php-coveralls/php-coveralls: ^2.4
- phpunit/phpcov: ^8.2
- phpunit/phpunit: ^9.5
- symfony/phpunit-bridge: ^5.4
- symfony/test-pack: ^1.0
- twig/twig: ^3.5
README
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 许可协议。