php - Laravel Service Providers 绑定多个实现,在依赖注入的时候,怎么确定是实例化的哪一个类?

 8023pxeb_256 发布于 2022-11-16 01:45
interface Pay 
{
    public function run();
}

class Weixin implements Pay 
{
    public function run()
    {
        echo 'weixin';
    }
}

class Ali implements Pay 
{
    public function run()
    {
        echo 'ali';
    }
}

class PayServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->singleton('weixin', function () {
            return new Weixin;
        });

        $this->app->singleton('ali', function () {
            return new Ali;
        });
    }
}

class A
{
    // 这里注入应该填入什么参数? 怎么确定注入的是哪个类的实例
    public functions __construct(Pay $pay)
    {
        
    }
}
1 个回答
  • 首先,你对服务容器(Service Container)的行为理解有误!

    第一,通过绑定服务ID的方式定义的服务,只能通过服务ID来获取,如下:

    // 定义服务
    $this->app->singleton('service_id', function () {
        return new Service();
    })
    
    // 获取服务,以下方式等价
    $this->app->make('service_id');
    $this->app['service_id'];

    第二,你想通过接口的类型提示(Type Hint)来自动解析并注入服务,需要像下边这样:

    // 绑定接口到实例
    $this->app->bind('Namespace\To\Your\Interface\Pay', 'Namespace\To\Your\Class\Weixin');

    如果你需要注入服务的对象是通过服务容器(Service Container)来解析的,才可以使用类型提示(Type Hint)来进行自动解析并注入服务。以下这些类的实例都是通过服务容器来解析的:controllers, event listeners, queue jobs, middleware等,以及自己绑定到服务容器(Service Container)的服务。

    第三,像上边这样,通过绑定接口到实例,只能自动解析为一个实例,也就是你绑定的实例;如果你想要的结果是,不同的类,构造器通过类型提示(Type Hint)相同的接口,注入不同的实例,可以像下边这样(上下文绑定,Context Binding):

    $this->app->when('Namespace\To\Your\Class\A')
              ->needs('Namespace\To\Your\Interface\Pay')
              ->give('Namespace\To\Your\Class\Weixin');
              
    $this->app->when('Namespace\To\Your\Class\B')
              ->needs('Namespace\To\Your\Interface\Pay')
              ->give('Namespace\To\Your\Class\Ali');

    通过上下文绑定,A的实例会注入Weixin的实例,而B的实例会注入Ali的实例。像下边:

    class A
    {
        public functions __construct(Pay $pay)
        {
            var_dump($pay instanceof Weixin); // True
        }
    }
    
    class B
    {
        public functions __construct(Pay $pay)
        {
            var_dump($pay instanceof Ali); // True
        }
    }
    2022-11-16 01:48 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有