Laravel: Nhà cung cấp dịch vụ (Service Providers)

 

Các nhà cung cấp dịch vụ là nơi trung tâm của tất cả quá trình khởi động ứng dụng Laravel. Ứng dụng của riêng bạn, cũng như tất cả các dịch vụ cốt lõi của Laravel, được khởi động thông qua các nhà cung cấp dịch vụ.

Nhưng, chúng ta có nghĩa là gì bởi “bootstrapped”? Nói chung, chúng tôi có nghĩa là đăng ký mọi thứ, bao gồm đăng ký ràng buộc vùng chứa dịch vụ, trình xử lý sự kiện, phần mềm trung gian và thậm chí cả các tuyến đường. Các nhà cung cấp dịch vụ là nơi trung tâm để cấu hình ứng dụng của bạn.

Nếu bạn mở config/app.phptệp được bao gồm trong Laravel, bạn sẽ thấy một providersmảng. Đây là tất cả các lớp của nhà cung cấp dịch vụ sẽ được tải cho ứng dụng của bạn. Theo mặc định, một tập hợp các nhà cung cấp dịch vụ cốt lõi của Laravel được liệt kê trong mảng này. Các nhà cung cấp này khởi động các thành phần Laravel cốt lõi, chẳng hạn như thư, hàng đợi, bộ nhớ cache và các thành phần khác. Nhiều nhà cung cấp trong số này là nhà cung cấp “trả chậm”, có nghĩa là họ sẽ không được tải theo mọi yêu cầu, mà chỉ khi dịch vụ mà họ cung cấp thực sự cần thiết.

Trong phần tổng quan này, bạn sẽ học cách viết các nhà cung cấp dịch vụ của riêng bạn và đăng ký chúng với ứng dụng Laravel của bạn.

 

Nếu bạn muốn tìm hiểu thêm về cách Laravel xử lý các yêu cầu và hoạt động nội bộ, hãy xem tài liệu của chúng tôi về vòng đời yêu cầu Laravel .

 

 

Tất cả các nhà cung cấp dịch vụ đều mở rộng Illuminate\Support\ServiceProviderlớp học. Hầu hết các nhà cung cấp dịch vụ đều chứa một registervà một bootphương thức. Trong registerphương thức, bạn chỉ nên liên kết mọi thứ vào vùng chứa dịch vụ . Bạn không bao giờ nên cố gắng đăng ký bất kỳ trình lắng nghe sự kiện, tuyến đường hoặc bất kỳ phần chức năng nào khác trong registerphương thức.

Artisan CLI có thể tạo một trình cung cấp mới thông qua make:providerlệnh:

php artisan make:provider RiakServiceProvider

 

Như đã đề cập trước đây, trong registerphương thức này, bạn chỉ nên liên kết mọi thứ vào vùng chứa dịch vụ . Bạn không bao giờ nên cố gắng đăng ký bất kỳ trình lắng nghe sự kiện, tuyến đường hoặc bất kỳ phần chức năng nào khác trong registerphương thức. Nếu không, bạn có thể vô tình sử dụng dịch vụ được cung cấp bởi nhà cung cấp dịch vụ chưa được tải.

Chúng ta hãy xem xét một nhà cung cấp dịch vụ cơ bản. Trong bất kỳ phương thức nào của nhà cung cấp dịch vụ, bạn luôn có quyền truy cập vào thuộc $apptính cung cấp quyền truy cập vào vùng chứa dịch vụ:

<?php

namespace

App\Providers;

use

App\Services\Riak\Connection;

use

Illuminate\Support\ServiceProvider;

class

RiakServiceProvider

extends

ServiceProvider

{

/** * Register any application services. * * @return void */

public

function

register

() {

$this

->

app

->

singleton

(Connection::

class

,

function

(

$app

) {

return

new

Connection

(

config

(

'riak'

)); }); } }

Nhà cung cấp dịch vụ này chỉ định nghĩa một registerphương thức và sử dụng phương thức đó để xác định việc triển khai App\Services\Riak\Connectiontrong vùng chứa dịch vụ. Nếu bạn chưa quen với vùng chứa dịch vụ của Laravel, hãy xem tài liệu của nó .

 

Nếu nhà cung cấp dịch vụ của bạn đăng ký nhiều ràng buộc đơn giản, bạn có thể muốn sử dụng các thuộc tính bindingsvà singletonsthay vì đăng ký thủ công từng ràng buộc vùng chứa. Khi nhà cung cấp dịch vụ được tải bởi khuôn khổ, nó sẽ tự động kiểm tra các thuộc tính này và đăng ký các ràng buộc của chúng:

<?php

namespace

App\Providers;

use

App\Contracts\DowntimeNotifier;

use

App\Contracts\ServerProvider;

use

App\Services\DigitalOceanServerProvider;

use

App\Services\PingdomDowntimeNotifier;

use

App\Services\ServerToolsProvider;

use

Illuminate\Support\ServiceProvider;

class

AppServiceProvider

extends

ServiceProvider

{

/** * All of the container bindings that should be registered. * * @var array */

public

$bindings

= [ ServerProvider::

class

=> DigitalOceanServerProvider::

class

, ];

/** * All of the container singletons that should be registered. * * @var array */

public

$singletons

= [ DowntimeNotifier::

class

=> PingdomDowntimeNotifier::

class

, ServerProvider::

class

=> ServerToolsProvider::

class

, ]; }

 

Vì vậy, điều gì sẽ xảy ra nếu chúng tôi cần đăng ký một trình soạn nhạc xem trong nhà cung cấp dịch vụ của chúng tôi? Điều này nên được thực hiện trong bootphương pháp. Phương thức này được gọi sau khi tất cả các nhà cung cấp dịch vụ khác đã được đăng ký , có nghĩa là bạn có quyền truy cập vào tất cả các dịch vụ khác đã được đăng ký theo khuôn khổ:

<?php

namespace

App\Providers;

use

Illuminate\Support\Facades\View;

use

Illuminate\Support\ServiceProvider;

class

ComposerServiceProvider

extends

ServiceProvider

{

/** * Bootstrap any application services. * * @return void */

public

function

boot

() { View::

composer

(

'view'

,

function

() {

//

}); } }

 

Bạn có thể nhập gợi ý phụ thuộc cho bootphương pháp của nhà cung cấp dịch vụ của bạn . Vùng chứa dịch vụ sẽ tự động đưa vào bất kỳ phụ thuộc nào bạn cần:

use

Illuminate\Contracts\Routing\ResponseFactory;

/** * Bootstrap any application services. * * @param \Illuminate\Contracts\Routing\ResponseFactory $response * @return void */

public

function

boot

(ResponseFactory

$response

) {

$response

->

macro

(

'serialized'

,

function

(

$value

) {

//

}); }

 

Tất cả các nhà cung cấp dịch vụ đều được đăng ký trong config/app.phptệp cấu hình. Tệp này chứa một providersmảng nơi bạn có thể liệt kê tên lớp của các nhà cung cấp dịch vụ của mình. Theo mặc định, một tập hợp các nhà cung cấp dịch vụ cốt lõi của Laravel được liệt kê trong mảng này. Các nhà cung cấp này khởi động các thành phần Laravel cốt lõi, chẳng hạn như thư, hàng đợi, bộ nhớ cache và các thành phần khác.

Để đăng ký nhà cung cấp của bạn, hãy thêm nó vào mảng:

'providers'

=> [

// Other Service Providers

App\Providers\ComposerServiceProvider::

class

, ],

 

Nếu nhà cung cấp của bạn chỉ đăng ký các ràng buộc trong vùng chứa dịch vụ , bạn có thể chọn hoãn đăng ký cho đến khi một trong các ràng buộc đã đăng ký thực sự cần thiết. Việc hoãn tải nhà cung cấp như vậy sẽ cải thiện hiệu suất của ứng dụng của bạn, vì nó không được tải từ hệ thống tệp theo mọi yêu cầu.

Laravel biên dịch và lưu trữ danh sách tất cả các dịch vụ được cung cấp bởi các nhà cung cấp dịch vụ trả chậm, cùng với tên của lớp nhà cung cấp dịch vụ của nó. Sau đó, chỉ khi bạn cố gắng giải quyết một trong các dịch vụ này, Laravel mới tải nhà cung cấp dịch vụ.

Để trì hoãn việc tải trình cung cấp, hãy triển khai \Illuminate\Contracts\Support\DeferrableProvidergiao diện và xác định một providesphương pháp. Các providesphương pháp nên trả lại các ràng buộc chứa dịch vụ đăng ký bởi các nhà cung cấp:

<?php

namespace

App\Providers;

use

App\Services\Riak\Connection;

use

Illuminate\Contracts\Support\DeferrableProvider;

use

Illuminate\Support\ServiceProvider;

class

RiakServiceProvider

extends

ServiceProvider

implements

DeferrableProvider

{

/** * Register any application services. * * @return void */

public

function

register

() {

$this

->

app

->

singleton

(Connection::

class

,

function

(

$app

) {

return

new

Connection

(

$app

[

'config'

][

'riak'

]); }); }

/** * Get the services provided by the provider. * * @return array */

public

function

provides

() {

return

[Connection::

class

]; } }