Service Provider là gì?
Ở bài viết trước chúng ta đã tìm hiểu về Service Container, ở bài viết này chúng ta sẽ tìm hiểu về Service Provider.
Service Provider là nơi trung tâm của tất cả quá trình khởi tạo ứng dụng trong Laravel. Ứng dụng của bạn, cũng như các thành phần core của Laravel được khởi tạo từ Service Provider.
Service Provider trong laravel
Nếu bạn mở fileconfig/app.php
thì bạn có thể thấy được một mảng providers
được khai báo. Tất cả những Service Provider class này sẽ được load vào trong ứng dụng. Ngoài ra nếu các bạn để ý thì khi chúng ta sử dụng một package bên ngoài thì chúng ta đều buộc phải khai báo các Service Provider của chúng vào trong config/app.php
.
'providers' => [
/*
* Laravel Framework Service Providers...
*/
Illuminate\Auth\AuthServiceProvider::class,
Illuminate\Broadcasting\BroadcastServiceProvider::class,
Illuminate\Bus\BusServiceProvider::class,
Illuminate\Cache\CacheServiceProvider::class,
Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
Illuminate\Cookie\CookieServiceProvider::class,
Illuminate\Database\DatabaseServiceProvider::class,
Illuminate\Encryption\EncryptionServiceProvider::class,
Illuminate\Filesystem\FilesystemServiceProvider::class,
.....
]
Ở trong bài viết trước thì chúng ta đã biết để đăng ký các service binding thì chúng ta sẽ phải sử dụng app->bind()
, app->instance()
, app->singleton()
, nhưng ở trong mảng này thì chúng ta chỉ khai báo các lớp nhưng vẫn thực hiện được việc binding vậy chúng được thực hiện bằng cách nào?
Tất cả các class ở trên đều được kế thừa từ class Illuminate\Support\ServiceProvider
và trong class này có chứa method register
đây là nơi thực hiện việc binding các service.
Viết Service Provider
Bây giờ chúng ta sẽ viết ra một Service Provider để tìm hiểu rõ ràng hơn. Để sinh ra một provider thì chúng ta sử dụng câu lệnh dưới đây
$ php artisan make:provider TestServiceProvider
class TestServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
$this->app->singleton('test', function () {
return 'Testing...';
});
}
}
Register method
Bên trong hàm register
của Service Provider này chúng ta sẽ thực hiện việc binding một service có tên là test
vào trong container. Bạn không nên bao giờ cố gắng đăng kí bất kì event listeners, routes hay bất kì các chức năng nào khác vào trong hàm register
. Nếu không, bạn có thể vô tình sử dụng một service được cung cấp bởi một Service Provider mà chưa được load.
Deferred Providers
Nếu như muốn trì hoãn việc binding cho tới khi nào cần thiết thì chúng ta có thể sử dụng biến $defer
và set nó về true
để khai báo đây là một defered
provider.
protected $defer = true;
Boot method
Ngoài ra nếu như chúng ta muốn đăng ký một view composer vào trong Service Provider thì chúng ta có thể thực hiện việc này trong hàm boot
. Hàm này được gọi sau khi tất cả các Service Providers đã được đăng kí.
public function boot(DispatcherContract $events)
{
parent::boot($events);
view()->composer('view', function () {
//
});
}
Registering Provider
Và cuối cùng thì chúng ta phải đăng ký Service Provider chúng ta đã viết vào trong mảng providers
trong file config/app.php như ở trên đầu bài.
'providers' => [
App\Providers\TestServiceProvider::class,
],
Chúng ta có thể tổng kết lại là Service Provider có hai loại là defered và không phải defered ( kiểm tra bằng biến defer). Nếu như không phải defered thì laravel sẽ thực hiện việc binding ngay thông qua việc chạy hàm register còn nếu là defered provider thì sẽ không chạy hàm register, mà chỉ chạy khi được yêu cầu resolve.
Kết luận
Cảm ơn các bạn đã theo dõi bài viết, chúng ta đã cùng tìm hiểu về Service Provider. Mong bài viết đem lại cho các bạn những kiến thức hữu ích, hẹn gặp lại các bạn trong những bài viết lần sau.