以下に、サービスコンテナ、サービスプロバイダ、サービスクラス、コントローラクラス、モデルクラスを使用したコード例を示します。
1.サービスクラスの作成
// app/Services/PostService.php namespace App\Services; use App\Models\Post; class PostService { public function getAllPosts() { return Post::all(); } }
2.サービスプロバイダの作成と登録
// app/Providers/PostServiceProvider.php namespace App\Providers; use Illuminate\Support\ServiceProvider; use App\Services\PostService; class PostServiceProvider extends ServiceProvider { public function register() { $this->app->singleton(PostService::class, function ($app) { return new PostService(); }); } public function boot() { // } }
3.config/app.php の providers 配列に PostServiceProvider を追加して登録します。
// config/app.php 'providers' => [ // ... App\Providers\PostServiceProvider::class, ],
4.モデルクラスの作成
// app/Models/Post.php namespace App\Models; use Illuminate\Database\Eloquent\Model; class Post extends Model { protected $fillable = ['title', 'body']; }
5.コントローラクラスの作成
// app/Http/Controllers/PostController.php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Services\PostService; class PostController extends Controller { protected $postService; public function __construct(PostService $postService) { $this->postService = $postService; } public function index() { $posts = $this->postService->getAllPosts(); return view('posts.index', compact('posts')); } }
6.ルーティングの設定
// routes/web.php use App\Http\Controllers\PostController; Route::get('/posts', [PostController::class, 'index']);
このコード例では、PostService サービスクラスを作成し、PostServiceProvider でサービスコンテナに登録しています。PostController コントローラクラスでは、コンストラクタインジェクションを使用して PostService のインスタンスを取得し、ビジネスロジックを実行しています。最後に、ルーティングでコントローラの index メソッドにリクエストをディスパッチしています。
記の例では、サービスプロバイダを使用してサービスコンテナへの登録を行っていますが、Laravelではサービスコンテナが自動的にクラスの依存関係を解決し、インスタンスを生成できます。従って、サービスプロバイダの作成とサービスコンテナへの登録がなくても、このケースでは動作します。
異なる実装やインターフェースを使用する場合の具体例として、メール送信機能を考えます。メール送信機能には、さまざまなメールサービス(SMTP、SendGrid、Mailgun など)を使用することができます。インターフェースと異なる実装を用いて、アプリケーションの構成を簡単に変更できるようにします。
1.インターフェースの作成
// app/Contracts/Mailer.php namespace App\Contracts; interface Mailer { public function send(string $to, string $subject, string $body); }
2.異なる実装の作成 SMTPを使った実装:
// app/Services/SmtpMailer.php namespace App\Services; use App\Contracts\Mailer; class SmtpMailer implements Mailer { public function send(string $to, string $subject, string $body) { // SMTPを使ってメールを送信するロジック } }
3.SendGridを使った実装:
// app/Services/SendGridMailer.php namespace App\Services; use App\Contracts\Mailer; class SendGridMailer implements Mailer { public function send(string $to, string $subject, string $body) { // SendGridを使ってメールを送信するロジック } }
4.サービスプロバイダの作成と登録
// app/Providers/MailServiceProvider.php namespace App\Providers; use Illuminate\Support\ServiceProvider; use App\Contracts\Mailer; use App\Services\SmtpMailer; use App\Services\SendGridMailer; class MailServiceProvider extends ServiceProvider { public function register() { $this->app->singleton(Mailer::class, function ($app) { // 実装を切り替えるための条件分岐 $mailer = config('mail.mailer'); if ($mailer === 'smtp') { return new SmtpMailer(); } elseif ($mailer === 'sendgrid') { return new SendGridMailer(); } throw new \Exception('Invalid mailer configuration.'); }); } public function boot() { // } }
5.config/app.php の providers 配列に MailServiceProvider を追加して登録します。
// app/Http/Controllers/MailController.php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Contracts\Mailer; class MailController extends Controller { protected $mailer; public function __construct(Mailer $mailer) { $this->mailer = $mailer; } public function sendMail() { $to = 'example@example.com'; $subject = 'Test Mail'; $body = 'This is a test mail.'; $this->mailer->send($to, $subject, $body); return 'Mail sent.'; } }
この例では、メール送信機能のインターフェースMailerを定義し、異なる実装(SmtpMailerSmtpMailer と SendGridMailer)を作成しました。MailServiceProvider を使って、アプリケーションの設定に基づいて実装を切り替えることができます。
この方法の利点は、メール送信機能を使用するすべての箇所でインターフェース Mailer を使ってコーディングすることで、実装が柔軟に切り替えられる点です。例えば、メール送信サービスを変更したい場合、config/mail.php の設定を変更するだけで、アプリケーション全体で新しいメール送信サービスが適用されます。
サービスプロバイダとサービスコンテナを使用することで、アプリケーションの依存関係が一元管理され、コードの整理やメンテナンスが容易になります。また、アプリケーションの構成を変更することで、実装を簡単に切り替えることが可能です。