サービスプロバイダーの作成

前回はサービスプロバイダーの仕組みを既存のコードを追って理解しました。今回は自分でサービスプロバイダーを作成して、その中でサービスコンテナへサービスを登録してみます。


サービスの作成

まずは、簡単なサービスを作成します。
app/Servicesディレクトリに Messengerディレクトリを作成し、Messengerサービスと位置付けます。Messengerインターフェースと、その実装である MailMessenger, BikeMessengerクラスを作成します。

<?php // app/Services/Messenger/Messenger.php

namespace App\Services\Messenger;

interface Messenger {
	public function send($message);
}
<?php  // app/Services/Messenger/MailMessenger.php

namespace App\Services\Messenger;

class MailMessenger implements Messenger {

	public function send($message) {
		// ここで、メールでメッセージを送る

		return "メールで $message を送りました。";
	}
}
<?php  // app/Services/Messenger/BikeMessenger.php

namespace App\Services\Messenger;

class BikeMessenger implements Messenger {

	public function send($message) {
		// ここで、バイクに乗ってメッセージを届ける

		return "バイク便で $message を届けました。";
	}
}

ルーティング

Messengerを使用する、ルート設定を行います。

// app/Http/routes.php

use App\Services\Messenger\Messenger;

Route::get('send_message/{message}', function(Messenger $messenger, $message){
	return $messenger->send($message);
});

ここでは、コントローラを作成せずに、クロージャーを使ってアクションを定義します。オプションパラメータ $messge を受け取り、それをMessengerサービスに渡し、戻り値を画面に表示しています。
クロージャーでは、タイプヒントで依存注入を行い、Messengerインターフェースのインスタンスを受け取ります。

この時点で、 http://localhost:8000/send_message/SOME_MESSAGE にアクセスすると。Laravelは、Mesengerインターフェースに対して、どのクラスのインスタンスを生成してよいか分からない為、以下のようにエラーとなります。

Target [App\Services\Messenger\Messenger] is not instantiable.

AppServiceProvider

自分でサービスプロバイダーを作成する前に、まずは、AppServiceProviderを使ってみます。

Laravelでは、アプリケーション固有の初期処理を実装する場所として、app/Providers/AppServiceProvider.php があります。この中で、今回作成した Messengerサービスをコンテナへ登録してみます。

<?php // app/Providers/AppServiceProvider.php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider {
	public function boot()
	{
		//
	}

	public function register()
	{
		$this->app->bind(
			'Illuminate\Contracts\Auth\Registrar',
			'App\Services\Registrar'
		);

		// Messengerサービスのバインド
		$this->app->bind(  // ① 追加
			'App\Services\Messenger\Messenger',
			'App\Services\Messenger\MailMessenger'  // メール便
		);	
//		$this->app->bind( // ② 追加
//			'App\Services\Messenger\Messenger',
//			'App\Services\Messenger\BikeMessenger'  // バイク便
//		);
	}
}

① Messengerインターフェースに対して、MailMessengerクラスをインスタンスを生成するよう支持しています。
② BikeMessengerに切り替えたい場合は、こちらを使います。

この時点で、 http://localhost:8000/send_message/重要書類 にアクセスすると、下記のように表示されます。

メールで 重要書類 を送りました。

②のBikeMessengerに切り替えて http://localhost:8000/send_message/重要書類 にアクセスすると、以下のように表示されます。

バイク便で 重要書類 を届けました。

次に自分でサービスプロバイダーを作成したいと思います。
先ほどのAppServiceProvider内の①②のコードは、ここで削除してください。


サービスプロバイダーの作成

サービスプロバイダーは artisan コマンドで作成します。

php artisan make:provider MessengerProvider

app/Providers/MessengerProvider.php が作成されました。

AppServiceProviderの時と同様に、Messengerサービスをコンテナへバインドするコードを追加します。

<?php  // app/Providers/MessengerServiceProvider.php
namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class MessengerServiceProvider extends ServiceProvider {
	public function boot()
	{
		//
	}

	public function register()
	{
		// Messengerサービスのバインド
		$this->app->bind(  // ① 追加
			'App\Services\Messenger\Messenger',
			'App\Services\Messenger\MailMessenger'  // メール便
		);	
//		$this->app->bind( // ② 追加
//			'App\Services\Messenger\Messenger',
//			'App\Services\Messenger\BikeMessenger'  // バイク便
//		);
	}

}

次に、Laravelが起動処理の中で MessengerServiceProviderをコールするように、config/app.php に MessengerServiceProviderを追加します。

<?php // config/app.php

// …

return [
    'providers' => [
        // ...

        /*
         * Application Service Providers...
         */
        App\Providers\AppServiceProvider::class,
        App\Providers\EventServiceProvider::class,
        App\Providers\RouteServiceProvider::class,
        App\Providers\MessengerProvider::class, // 追加
        // ...
    ],

    // ...
];

ここで、 http://localhost:8000/send_message/重要書類 にアクセスすると、下記のように表示されます。

メールで 重要書類 を送りました。

まとめ

  • サービスコンテナのバインディングはサービスプロバイダーで行う。
  • アプリケーション固有のサービスプロバイダーは AppServiceProvider.php。
  • サービスプロバイダーは artisan make:provider コマンドで作成する。

公式サイト
http://laravel.com/docs/5.1/providers

コメントを残す