symfony 装饰服务教程(2) langziyang Symfony博客 356 views 在前面我们通过extends原始服务达到了装饰的目的,接下来我们再看实现装饰服务的另一种方式。 我们在自己开发的过程中,可能出入个人原因,很少写interface,但是有一些服务为了扩展方便而使用interface是最好的开发模式,接下来我们通过interface方式来装饰自己的服务。 首先我们新建一个ServiceInterface.php ``` <?phpnamespace App\Services; interface ServiceInterface { public function doSomething(); } ``` 修改OriginalService.php和DecorationService.php,让其都实现这个接口: ``` <?phpnamespace App\Services; class OriginalService implements ServiceInterface { public function doSomething() { return 'Original service is doing something.'; } } ``` ``` <?phpnamespace App\Services; use Symfony\Component\DependencyInjection\Attribute\AsDecorator; #[AsDecorator(decorates: OriginalService::class)]class DecorationService implements ServiceInterface { public function doSomething() { return 'this is from decoration service'; } } ``` 同时修改控制器的方法,注入ServiceInterface ``` #[Route('/', name: 'app_index')]public function index(ServiceInterface $service): Response { dd($service->doSomething()); } ``` 然后刷新页面,你就得到了一个错误: # Cannot autowire argument $service of "App\Controller\IndexController::index()": it references interface "App\Services\ServiceInterface" but no such service exists. You should maybe alias this interface to one of these existing services: "App\Services\DecorationService", "App\Services\DecorationService.inner". 接下来我们修改 configservices.yaml文件 ``` App\Services\ServiceInterface: '@App\Services\OriginalService' ``` 保存后刷新,是不是又运行成功了? 接下来的问题是:使用继承方式装饰服务时,我们可以用parent::doSomething()调用OriginalService的方法。那使用接口的方式怎么调用呢?不要急,我们修改一下DecorationService.php ``` <?phpnamespace App\Services; use Symfony\Component\DependencyInjection\Attribute\AsDecorator; use Symfony\Component\DependencyInjection\Attribute\AutowireDecorated; #[AsDecorator(decorates: OriginalService::class)]class DecorationService implements ServiceInterface { public function __construct(#[AutowireDecorated] private $inner) { } public function doSomething() { return $this->inner->doSomething(); } } ``` 刷新你的页面,是不是看到了Original service is doing something?这就是整个流程,因为在symfony的第三方bundle中,很多服务都是通过接口注入的,所以我们常通过现在这种方式装饰。 帮助PHPZlc项目! 与任何开源项目一样, 贡献代码 或 文档 是最常见的帮助方式, 但我们也有广泛的 赞助机会。 2 赞赏 加入技术群 评论 去登录