Service Container란 무엇입니까
Laravel 서비스 컨테이너는 클래스 종속성을 관리하고 종속성 주입을 수행하는 강력한 도구입니다.
Laravel 공식에서 Service Container에 대한 설명을 읽을 수 있습니다. 문서화 보시다시피, 그 역할은 종속성 주입을 관리하고 수행하는 데 도움을 주는 것입니다.
서비스 컨테이너를 사용하는 이유
"종속성 주입"에서 종속성 주입을 사용하면 코드 결합을 크게 줄일 수 있지만 주입된 개체를 직접 관리해야 한다는 단점도 따른다는 것을 확인했습니다.
구성 요소에 종속성이 많은 경우 종속성을 전달하기 위해 여러 매개 변수가 있는 setter 메서드를 생성하거나 이를 전달하기 위해 여러 매개 변수가 있는 생성자를 만들어야 합니다. 또한 구성 요소를 사용하기 전에 매번 종속성을 생성해야 합니다. 우리 코드는 이렇게 유지 관리하기가 쉽지 않습니다.
따라서 종속 인스턴스에 대한 컨테이너(서비스 컨테이너)를 제공하는 것은 실용적이고 우아한 방법입니다.
예를 들어 다음은 laravel의 항목 파일입니다(설명이 제거되었습니다).
// 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;
먼저 bootstrap/app.php
를 살펴보세요. 여기서 $app
는 IlluminateFoundationApplication 및 IlluminateFoundationApplication
클래스는 컨테이너에서 상속되므로 $app
은 실제로 서비스 컨테이너입니다. 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
그런 다음 다음 세 가지 싱글톤 메서드는 IlluminateContractsHttpKernel
, IlluminateContractsConsoleKernel
, IlluminateContractsDebugExceptionHandler
세 가지 인터페이스에 의존할 때 어떤 싱글톤 클래스를 삽입할지 정의합니다.
public/index.php
를 살펴보세요. make 메소드는 실제로 서비스 컨테이너를 사용하여 새로운 IlluminateContractsHttpKernel
인스턴스를 생성합니다. 일반적인 new와의 차이점은 종속성을 추가한다는 것입니다. 자동으로 주입됩니다. 아주 간단하지 않나요? 실제로 Laravel뿐만 아니라 Yii2, Phalcon 등의 프레임워크도 모두 컨테이너를 구현하여 종속성 주입을 관리합니다. - 서비스 컨테이너 사용법컨테이너이기 때문에 물건을 넣고 빼는 일이 서비스 컨테이너에 해당하는 것이 바인딩과 해결입니다.
- Laravel의 Service Provider에서는
$this->app
을 통해 컨테이너를 가져올 수 있습니다. 또한app()
Get을 사용할 수도 있습니다. 컨테이너.Laravel 외부에서 서비스 컨테이너를 사용하는 경우 새로운
IlluminateContainerContainer
를 생성하여 컨테이너를 가져오세요. $container는 아래에서 획득한 컨테이너를 나타내는 데 사용됩니다.
Binding
- Binding은 인터페이스의 인스턴스를 반환합니다
-
//使用闭包 $container->bind('BarInterface', function(){ return new Bar(); }); //或者使用字符串 $container->bind('FooInterface', 'Foo');
로그인 후 복사
싱글턴 바인딩
- singletion 메서드는 컨테이너에 한 번만 구문 분석되는 클래스 또는 인터페이스를 바인딩하고 나중에 모든 호출을 호출합니다. 컨테이너에서 동일한 인스턴스를 반환합니다.
$container->singleton('BarInterface', function(){ return new Bar(); });
로그인 후 복사
Bind 인스턴스
- 인스턴스 메서드를 사용하여 기존 개체 인스턴스를 컨테이너에 바인딩할 수도 있습니다. 후속 호출은 컨테이너에서 지정된 인스턴스를 반환합니다.
$bar = new Bar(); $bar->setSomething(new Something); $container->instance('Bar', $bar);
로그인 후 복사
Context 바인딩때로는 동일한 인터페이스를 사용하는 두 개의 클래스가 있을 수 있지만 각 클래스가 서로 다른 작업을 주입할 수 있기를 원할 수 있습니다.
-
$container->when('Man') ->needs('PartnerInterface') ->give('Woman'); $container->when('Woman') ->needs('PartnerInterface') ->give('Man');
로그인 후 복사mark
- 때때로 특정 "카테고리" 아래의 모든 바인딩을 구문 분석해야 할 수도 있습니다.
$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')); });
- parse
- make method
$foo = $container->make('Foo');
array method
parse가 바인딩된 것으로 표시됨$bar = $container['Bar'];로그인 후 복사