Service Container的觀念滿抽象的,以下是其觀念:
Laravel 的 Service Container(服務容器)是框架中一個關鍵的功能,它是一種依賴注入(Dependency Injection)和服務解析(Service Resolution)的容器。它有助於簡化依賴注入、服務解析和管理相依性的過程,使您能夠更輕鬆地構建可維護和可測試的應用程序 - ChatGPT
上一篇使用的
public function index(PostService $postService) {
...
}
PostService $postService
就是使用Service Container
當然也可以不只注入一個,如:
public function index(PostService $postService, Request $request) {
...
}
提供綁定功能,綁定甚麼?
在注入的時候,決定該綁定到哪個Class
接著看吧
今天筆者想用這部影片
結合我們之前所使用的Post功能,增加限時貼文(expired_at)
今天沿用前面使用的Post表,新增type、expired_at
database\migrations\2023_09_19_164215_create_posts_table.php
public function up(): void
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->bigInteger('user_id')->default(0)->comment('關聯使用者')->index();
$table->text('title');
$table->text('content');
$table->integer('views')->default(0)->comment('觀看數');
$table->string('type', '20')->nullable();
$table->timestamp('expired_at')->nullable();
$table->timestamps();
$table->softDeletes();
});
}
在終端跑php artisan migrate:rollback && php artisan migrate
手動建立PostRepositoryInterface
app\Interfaces\PostRepositoryInterface.php
<?php
namespace App\Interfaces;
interface PostRepositoryInterface
{
public function get();
public function create(array $data): void;
}
app\Repositories\PostRepository.php
<?php
namespace App\Repositories;
use App\Interfaces\PostRepositoryInterface;
use App\Models\Post;
use Illuminate\Database\Eloquent\Collection;
class PostRepository implements PostRepositoryInterface
{
public function get(): Collection
{
return Post::where('type', 'post')
->orderBy('id', 'desc')
->get();
}
public function create($data): void
{
$data['type'] = 'post';
Post::create($data);
}
}
app\Repositories\StoryRepository.php
<?php
namespace App\Repositories;
use App\Interfaces\PostRepositoryInterface;
use App\Models\Post;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Collection;
class StoryRepository implements PostRepositoryInterface
{
public function get(): Collection
{
return Post::where('expired_at', '>', Carbon::now())
->where('type', 'story')
->orderBy('id', 'desc')
->get();
}
public function create($data): void
{
$data['expired_at'] = Carbon::now()->addDay();
$data['type'] = 'story';
Post::create($data);
}
}
php artisan make:provider PostServiceProvider
app\Providers\PostServiceProvider.php
<?php
namespace App\Providers;
use App\Interfaces\PostRepositoryInterface;
use App\Repositories\PostRepository;
use App\Repositories\StoryRepository;
use Illuminate\Support\ServiceProvider;
class PostServiceProvider extends ServiceProvider
{
/**
* Register services.
*/
public function register(): void
{
$this->app->bind(PostRepositoryInterface::class, function ($app){
if (request()->input('type') === 'story'){
return new StoryRepository();
} else {
return new PostRepository();
// default is normal post
}
});
}
/**
* Bootstrap services.
*/
public function boot(): void
{
//
}
}
config\app.php 加入 App\Providers\PostServiceProvider::class,
新增post
取得post
新增story
取得story
本篇簡單有實際例子演示如何使用Service Provider,註冊PostRepository到Service Container中
並在Service Provider作了一些判斷來演示其中的發展性
如以下幾個例子,比較生活化能應用的到:
銀行、各第三方訊息API(Line、Telegram、Discord...)、File Cloud(AWS、GCP...)
如果想多了解的話建議可以看開頭的影片,那我們下篇見~
如何理解 Laravel 的 IoC 容器
Laravel 6 Advanced - e1 - Service Container