将接口绑定到实现

最后更新于:2022-04-01 15:04:46

## 注入具体依赖 服务容器有个非常强大特色,能够绑定特定实例的接口。举例,假设我们应用程序要集成 Pusher 服务去收发即时事件,如果使用 Pusher 的 PHP SDK,可以在类注入一个 Pusher 客户端实例: ~~~ <?php namespace App\Handlers\Commands; use App\Commands\CreateOrder; use Pusher\Client as PusherClient; class CreateOrderHandler { /** * Pusher SDK 客户端实例 */ protected $pusher; /** * 创建一个实例 * * @param PusherClient $pusher * @return void */ public function __construct(PusherClient $pusher) { $this->pusher = $pusher; } /** * 执行命令 * * @param CreateOrder $command * @return void */ public function execute(CreateOrder $command) { // } } ~~~ 在上面这个例子中,注入类的依赖到类中已经能够满足需求;但同时,我们也紧密耦合于 Pusher 的 SDK 。如果 Pusher 的 SDK 方法发生改变,或者我们要切换到别的事件服务,那我们也需要同时修改 CreateOrderHandler 的代码。 ## 为接口编程 为了将 CreateOrderHandler 和事件推送的修改「隔离」,我们可以定义一个 EventPusher 接口和一个 PusherEventPusher 实现: ~~~ <?php namespace App\Contracts; interface EventPusher { /** * Push a new event to all clients. * * @param string $event * @param array $data * @return void */ public function push($event, array $data); } ~~~ 一旦 PusherEventPusher 实现这接口,就可以在服务容器像这样注册它: `$this->app->bind('App\Contracts\EventPusher', 'App\Services\PusherEventPusher');` 当有类需要 EventPusher 接口时,会告诉容器应该注入 PusherEventPusher,现在就可以在构造器中「类型指定」一个 EventPusher 接口: ~~~ /** * Create a new order handler instance. * * @param EventPusher $pusher * @return void */ public function __construct(EventPusher $pusher) { $this->pusher = $pusher; } ~~~
';