Was ist Service Container?
Der Laravel Service Container ist ein leistungsstarkes Tool zum Verwalten von Klassenabhängigkeiten und zur Durchführung der Abhängigkeitsinjektion.
Sie können die Erklärung des Service Containers vom Laravel-Beamten lesen Dokumentation Wie Sie sehen, besteht seine Aufgabe darin, uns bei der Verwaltung und Durchführung der Abhängigkeitsinjektion zu unterstützen.
Warum Service Container verwenden?
In „Abhängigkeitsinjektion“ haben wir gesehen, dass die Verwendung von Abhängigkeitsinjektion die Koppelung des Codes erheblich reduzieren kann, aber auch einen Nachteil mit sich bringt, nämlich dass Sie die injizierten Objekte selbst verwalten müssen.
Wenn eine Komponente viele Abhängigkeiten hat, müssen wir eine Setter-Methode mit mehreren Parametern erstellen, um die Abhängigkeiten zu übergeben, oder einen Konstruktor mit mehreren Parametern erstellen, um sie zu übergeben. Darüber hinaus müssen wir jedes Mal Abhängigkeiten erstellen, bevor wir die Komponente verwenden Dadurch ist unser Code nicht einfach zu warten.
Die Bereitstellung eines Containers (Service Container) für abhängige Instanzen ist daher eine praktische und elegante Methode.
Das Folgende ist zum Beispiel die Eintragsdatei von Laravel (Kommentare wurden entfernt):
// public/index.php <?php require __DIR__.'/../bootstrap/autoload.php'; $app = require_once __DIR__.'/../bootstrap/app.php'; $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class); $response = $kernel->handle( $request = Illuminate\Http\Request::capture() ); $response->send(); $kernel->terminate($request, $response);
// bootstrap/app.php <?php $app = new Illuminate\Foundation\Application( realpath(__DIR__.'/../') ); $app->singleton( Illuminate\Contracts\Http\Kernel::class, App\Http\Kernel::class ); $app->singleton( Illuminate\Contracts\Console\Kernel::class, App\Console\Kernel::class ); $app->singleton( Illuminate\Contracts\Debug\ExceptionHandler::class, App\Exceptions\Handler::class ); return $app;
Schauen Sie sich zunächst bootstrap/app.php
an, wobei $app
IlluminateFoundationApplicationEine Instanz der Klasse, und die Klasse IlluminateFoundationApplication
erbt vom Container, sodass $app
eigentlich ein Service-Container ist. bootstrap/app.php
,其中$app
是IlluminateFoundationApplication
的一个实例,而IlluminateFoundationApplication
类继承自Container,所以$app
实际上就是一个Service Container。
然后下面的三个singleton方法定义了当依赖IlluminateContractsHttpKernel
、IlluminateContractsConsoleKernel
、IlluminateContractsDebugExceptionHandler
这三个接口时,注入哪个类的单例。
然后看public/index.php
,其中的make方法实际上就是用Service Container来new一个IlluminateContractsHttpKernel
实例,跟普通new的区别就是会把他的依赖自动注入进去。
是不是很简洁?
其实不单是Laravel,像Yii2、Phalcon等框架都通过实现容器来管理依赖注入。
如何使用Service Container
既然是一个容器,无非就是两个事,往里放东西和往外取东西,对应到Service Container就是绑定(Binding)和解析(Resolving)。
获得容器
在Laravel的Service Provider中,可以通过$this->app
获取容器,除此之外,还可以使用app()
来获取容器。
如果在Laravel外使用Service Container,直接new一个IlluminateContainerContainer
Dann definieren die folgenden drei Singleton-Methoden, welche Singleton-Klasse eingefügt werden soll, wenn sie sich auf die drei Schnittstellen IlluminateContractsHttpKernel
, IlluminateContractsConsoleKernel
, IlluminateContractsDebugExceptionHandler
verlassen.
public/index.php
an. Die make-Methode verwendet tatsächlich den Service Container, um eine neue IlluminateContractsHttpKernel
-Instanz zu erstellen Automatisch eingespritzt. Ist es nicht ganz einfach? Tatsächlich verwalten nicht nur Laravel, sondern auch Frameworks wie Yii2 und Phalcon die Abhängigkeitsinjektion durch die Implementierung von Containern. - So verwenden Sie einen Service-ContainerDa es sich um einen Container handelt, sind es nichts weiter als zwei Dinge: das Einlegen und Herausnehmen von Dingen. Die entsprechenden Dinge für den Service-Container sind bindend und lösend.
- Im Laravel-Dienstanbieter können Sie den Container über
$this->app
abrufen. Darüber hinaus können Sie auchapp()
Get verwenden Der Behälter.Wenn Sie Service Container außerhalb von Laravel verwenden, erstellen Sie einfach einen neuen
IlluminateContainerContainer
, um den Container zu erhalten. $container wird unten verwendet, um den erhaltenen Container darzustellen.
Binding
- Binding gibt eine Instanz der Schnittstelle zurück gibt dieselbe Instanz aus dem Container zurück:
-
//使用闭包 $container->bind('BarInterface', function(){ return new Bar(); }); //或者使用字符串 $container->bind('FooInterface', 'Foo');
Nach dem Login kopieren
- Sie können die Instanzmethode auch verwenden, um eine vorhandene Objektinstanz an den Container zu binden. Nachfolgende Aufrufe geben die angegebene Instanz aus dem Container zurück:
-
$container->singleton('BarInterface', function(){ return new Bar(); });
Nach dem Login kopieren
- Manchmal haben Sie möglicherweise zwei Klassen, die dieselbe Schnittstelle verwenden, aber Sie möchten, dass jede Klasse unterschiedliche Ergebnisse einbringen kann.
-
$bar = new Bar(); $bar->setSomething(new Something); $container->instance('Bar', $bar);
Nach dem Login kopieren
Manchmal müssen Sie möglicherweise alle Bindungen unter einer bestimmten „Kategorie“ analysieren.
$container->when('Man') ->needs('PartnerInterface') ->give('Woman'); $container->when('Woman') ->needs('PartnerInterface') ->give('Man');
-
$container->bind('Father', function () { // }); $container->bind('Mother', function () { // }); $container->bind('Daughter', function () { // }); $container->bind('Son', function () { // }); $container->tag(['Father', 'Mother', 'Daughter', 'Son'], 'familyMembers'); $container->bind('Family', function ($container) { return new Family($container->tagged('familyMembers')); });
Nach dem Login kopieren
-
$foo = $container->make('Foo');
Nach dem Login kopieren
$bar = $container['Bar'];Nach dem Login kopierenParse-Ereignis
Immer wenn der Service-Container ein Objekt auflöst. Das Ereignis wird ausgelöst. Sie können dieses Ereignis mithilfe der Auflösungsmethode abhören. Verwandte Empfehlungen:Die neuesten fünf Laravel-Video-Tutorials