首頁  >  文章  >  後端開發  >  Laravel Service Providers 綁定多個實現,在依賴注入的時候,怎麼確定是實例化的哪一個類別?

Laravel Service Providers 綁定多個實現,在依賴注入的時候,怎麼確定是實例化的哪一個類別?

WBOY
WBOY原創
2016-08-04 09:21:502158瀏覽

<code>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)
    {
        
    }
}
</code>

回覆內容:

<code>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)
    {
        
    }
}
</code>

首先,你對服務容器(Service Container)的行為理解有誤!

第一,透過綁定服務ID的方式定義的服務,只能透過服務ID來獲取,如下:

<code>// 定义服务
$this->app->singleton('service_id', function () {
    return new Service();
})

// 获取服务,以下方式等价
$this->app->make('service_id');
$this->app['service_id'];</code>

第二,你想透過介面的型別提示(Type Hint)來自動解析並注入服務,需要像下邊這樣:

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

如果你需要注入服務的物件是透過服務容器(Service Container)來解析的,才可以使用型別提示(Type Hint)來進行自動解析並注入服務。以下這些類別的實例都是透過服務容器來解析的:controllers, event listeners, queue jobs, middleware等,以及自己綁定到服務容器(Service Container)的服務。

第三,像上邊這樣,透過綁定介面到實例,只能自動解析為一個實例,也就是你綁定的實例;如果你想要的結果是,不同的類,建構器透過類型提示( Type Hint)相同的接口,注入不同的實例,可以像下邊這樣(上下文綁定,Context Binding):

<code>$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');</code>

透過上下文綁定,A的實例會注入Weixin的實例,而B的實例會注入Ali的實例。像下邊:

<code>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
    }
}</code>
陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn