Tự tạo Service Provider
Bài đăng này đã không được cập nhật trong 5 năm
1. Lí do nên tự viết Service Provider
Xin chào các bạn, mình đã trở lại đây. Trong bài viết này mình sẽ hướng dẫn mọi người tự tạo ra các provider để làm giảm nhẹ sức nặng của AppServiceProvider
.
Đối với 1 ứng dụng Laravel lớn khi mà bạn phải bootstrap
quá nhiều thứ vàoAppServiceProvider
. Điều này thực sự sẽ là thảm họa khi ai đó phải maintain
cái project của bạn. Bạn cảm giác như file AppServiceProvider.php
dài vô tận. Và bạn nghĩ mình phải tạo ra các service riêng.
Trong khuôn khổ bài viết này mình sẽ đặt ra tình huống ứng dựng có sử dụng Repository Design Partern
để binding một Interface với một Implementation đối với mỗi Model
để làm tầng trung gian giữa Controller
với Model
. Các bạn có thể xem chi tiết hơn về Repository Với Laravel ở bài viết này của mình
. Viết Repository Sạch Hơn Trong Laravel
Lúc này AppServiceProvider
chúng ta phải đăng kí như sau
<?php
namespace App\Providers;
use App\Libraries\Countries\CountriesManager;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
$this->app->bind(UserRepositoryInterface::class, UserRepository::class);
}
}
Nhưng sau đó ứng dụng của mình lại sử dụng Model event (Lại khoe cây nhà lá vườn trồng được)
Khi đó function boot()
ta lại phải thêm code để xử lí event model
<?php
namespace App\Providers;
use App\Libraries\Countries\CountriesManager;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
$this->app->bind(UserRepositoryInterface::class, UserRepository::class);
Group::observe(GroupObserver::class);
}
}
Rồi sau đó ứng dựng lại sử dụng Service để dùng chung một số hàm, chúng ta lại phải binding một Interface với một Implementation đối với từng service. Vậy là AppServiceProvider
của chúng ta sẽ khá cồng kềnh. Vậy là chúng ta nghĩ đến việc tách ra thành từng service riêng : RepositoryServiceProvider
, ModelEventServiceProvider
. . .
2. Triển khai viết Service Provider
Ở đây mình sẽ triển khai viết Service Provider cho Repository. Bước đầu tiên là tạo 1 class có tên RepositoryServiceProvider.php
nằm cùng cấp với thằng AppServiceProvider.php
. Bên trong mình cũng khai báo sẵn 2 phương thức boot()
và register()
.
<?php
namespace App\Providers;
class RepositoryServiceProvider extends ServiceProvider
{
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = true;
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
//
}
/**
* Register Interface::Class with container.
*
* @return void
*/
public function register()
{
$this->registerPermissionRepository();
}
/**
* register PermissionRepository
*
* @return void
*/
public function registerPermissionRepository()
{
$this->app->bind(PermissionRepositoryInterface::class, PermissionRepository::class);
}
}
Thực ra nó ở đây mình chỉ clone từ thằng AppServiceProvider
ra thôi mục đích để làm phân tán để giảm nhẹ sức nặng khi viết chung vào 1 class.
Bức tiếp theo là phải đăng kí RepositoryServiceProvider
vừa tạo trong config/app.php
'providers' => [
/*
* Laravel Framework Service Providers...
*/
...
App\Providers\RepositoryServiceProvider::class,
Do cấu hình được cache nên những thay đổi trong config/app.php không được tải lại nên nó thiếu RepositoryServiceProvider.php của mình. Nên để chắc chắc nó đãn được binding
vào app()
chúng ra phải chạy 2 lệnh sau
php artisan config:clear
php artisan cache:clear
Vậy là chúng ta đã tạo thành công 1 ServiceProvider
.
Ở đây mình muốn giải thích thêm một chút về thuộc tính protected $defer
trong RepositoryServiceProvider
.
Đầu tiên ứng dụng sẽ check xem biến $defer là true hay false. Nếu là false thì thực hiện ngay việc binding thông qua việc chạy hàm register.
Nếu $defer là true thì không chạy hàm register, thay vào đó sẽ lưu lại thông tin về việc service provider đó sẽ trả về service gì thông qua kết quả của hàm provides.
Việc load các service một cách defer như vậy sẽ giúp cái thiện performance cho application của bạn, khi mà những service chỉ được load khi mà nó là cần thiết.
3. Tổng kết
Vậy là mình đã giới thiệu các bạn tại sao nên tách riêng ra thành các provider và thực hiện việc tự tạo RepositoryServiceProvider
.
Việc tự tạo cách ServiceProvider
giúp code của bạn sáng sủa hơn, đồng làm làm giảm gánh nặng cho AppServiceProvider
. Đồng thời mọi người nhìn vào code của bạn cũng nhìn bạn với con mắt master
hơn
4. Tham khảo
All rights reserved