Heim  >  Artikel  >  Backend-Entwicklung  >  Laravel Service Providers bindet mehrere Implementierungen. Wie kann festgestellt werden, welche Klasse während der Abhängigkeitsinjektion instanziiert wird?

Laravel Service Providers bindet mehrere Implementierungen. Wie kann festgestellt werden, welche Klasse während der Abhängigkeitsinjektion instanziiert wird?

WBOY
WBOYOriginal
2016-08-04 09:21:502156Durchsuche

<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>

Antwortinhalt:

<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>

Erstens haben Sie ein falsches Verständnis vom Verhalten des Service-Containers (Service Container)!

Erstens können durch den verbindlichen Dienst ID definierte Dienste nur über den Dienst ID wie folgt erhalten werden:

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

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

Zweitens, wenn Sie Dienste automatisch über den Typhinweis der Schnittstelle (Type Hint) analysieren und einfügen möchten, müssen Sie etwa Folgendes tun:

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

Wenn das Objekt, das Sie in den Dienst einfügen müssen, über den Dienstcontainer (Service Container) analysiert wird, können Sie Typhinweise (Type Hint) verwenden, um den Dienst automatisch zu analysieren und einzufügen. Instanzen der folgenden Klassen werden über den Service-Container aufgelöst: controllers, event listeners, queue jobs, middleware usw. sowie an den Service-Container (Service Container) gebundene Dienste.

Drittens kann die Schnittstelle, wie oben beschrieben, nur an eine Instanz gebunden werden. Dies ist die Instanz, die Sie binden. Wenn das gewünschte Ergebnis eine andere Klasse ist, verwendet der Konstruktor Typhinweise (Type Hint) Dieselbe Schnittstelle kann wie folgt in verschiedene Instanzen eingefügt werden (Kontextbindung, 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>

Durch die Kontextbindung wird die Instanz von A in die Instanz von Weixin und die Instanz von B in die Instanz von Ali eingefügt. Wie unten:

<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>
Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn