サービスコンテナにサービスが反映されない
自己解決したのでいったん削除しましたが、誰かの役に立つかもしれないので再掲します。
Laravel 5.1
の環境で、ライブラリの開発を行おうとしています。
まず、作成直後のプロジェクトに、extlib/vendor/codename
というフォルダーを作り、そこを開発するライブラリの置き場所にすることにしました。このパスを認識させるために、composer.json
に以下のパスを追加し、composer dumpautoload
を行いました。
(前略)
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/",
"codename\\": "extlib/vendor/codename" 註:この行を追加
}
},
(後略)
この配下にservice
. provider
, facade
といったフォルダーを作成し、サービス用のクラスや、サービスプロバイダークラス、ファサードクラスを作成して置いてあります。
この設定の中で、Foo
サービスをFooProvider
でsingleton
登録し、さらにFooFacade
を通して使おうとしています。
<?php // Fooサービス
namespace codename\service;
class Foo
{
public function getMessage()
{
return 'ごきげんよう';
}
}
<?php // FooProviderサービスプロバイダー
namespace codename\provider;
use Illuminate\Support\ServiceProvider;
use codename\service\Foo;
class FooProvider extends ServiceProvider
{
protected $defer = true;
public function register()
{
$this->app->singleton('ex-foo', function ($app) {
return new Foo();
});
}
public function boot()
{
\Log::info(app()->getBindings()); // ex-fooは一覧にある。
\Log::info(app('ex-foo')->getMessage()); // これは出力される
}
}
boot
メソッドに記述したログ出力は期待通りに出力されているため、サービスコンテナへの登録はうまくいっているものと考えました。
しかし、確認のためにroutes.php
に以下のようなルーティングを追加して、内容表示を試みたところ、Class ex-foo does not exist
となってしまいます。同様に、バインド一覧を確認しましたが、やはり一覧には登録がありませんでした。
Route::get('test', function () {
\Log::info(app()->getBindings()); // 一覧にはex-fooはない。
// $s = new codename\service\Foo(); // こちらはOK
// $s = app()->make('ex-foo'); // Class ex-foo does not exist
$s = app('ex-foo'); // Class ex-foo does not exist
return $s->getMessage();
});
ちなみに、Facade
経由の場合もClass ex-foo does not exist
となります。主因はそれ以前にあるので、こちらは省略します。あたかも、違うサービスコンテナを見ているような状況なのですが、Laravelの経験が浅いためその理由がつかめません。解決方法やヒントをお持ちでしたら、ご教授いただけないでしょうか。