短編小説: composer ( https://packagist.org/packages/illuminate/container )を使用してインストールされた Laravel コンテナーでメソッド インジェクションが機能しません。インジェクションは、オブジェクトのコンストラクターで使用された場合にのみ機能します。例えば:
class SomeClass {
function __construct(InjectedClassWorksHere $obj) {}
function someFunction(InjectedClassFailsHere $obj) {}
}
長い話: 私は主要なプロジェクトをリファクタリングして Laravel を使用することを検討していましたが、ビジネス上のプレッシャーのために、希望する時間に投資することができません。「お風呂の水で赤ちゃんを捨てない」ために、私は個々のLaravelコンポーネントを使用して、古いブランチで開発されているコードの優雅さを高めています。Laravel を評価する際に私が気に入った新しいテクニックの 1 つは、依存性注入の概念でした。後で、Laravel プロジェクトの外で使用できることを知ってうれしく思いました。オンラインで見つかったコンテナの開発バージョンがメソッドインジェクションをサポートしていないように見えることを除いて、私はこれを機能させ、すべて順調です。
他の誰かがコンテナーを動作させ、Laravel プロジェクトの外部でメソッド インジェクションを行うことができましたか?
これまでの私のアプローチ...
composer.json
"illuminate/support": "5.0.*@dev",
"illuminate/container": "5.0.*@dev",
アプリケーションのブートストラップ コード:
use Illuminate\Container\Container;
$container = new Container();
$container->bind('app', self::$container); //not sure if this is necessary
$dispatcher = $container->make('MyCustomDispatcher');
$dispatcher->call('some URL params to find controller');
上記により、コントローラーのコンストラクターに注入できますが、メソッドのメソッドには注入できません。私は何が欠けていますか?
完全なソース... (C:\workspace\LMS>php cmd\test_container.php)
<?php
// This sets up my include path and calls the composer autoloader
require_once "bare_init.php";
use Illuminate\Container\Container;
use Illuminate\Support\ClassLoader;
use Illuminate\Support\Facades\Facade;
// Get a reference to the root of the includes directory
$basePath = dirname(dirname(__FILE__));
ClassLoader::register();
ClassLoader::addDirectories([
$basePath
]);
$container = new Container();
$container->bind('app', $container);
$container->bind('path.base', $basePath);
class One {
public $two;
public $say = 'hi';
function __construct(Two $two) {
$this->two = $two;
}
}
Class Two {
public $some = 'thing';
public function doStuff(One $one) {
return $one->say;
}
}
/* @var $one One */
$one = $container->make(One);
var_dump($one);
print $one->two->doStuff();
上記を実行すると...
C:\workspace\LMS>php cmd\test_container.php
object(One)#9 (2) {
["two"]=>
object(Two)#11 (1) {
["some"]=>
string(5) "thing"
}
["say"]=>
string(2) "hi"
}
PHP Catchable fatal error: Argument 1 passed to Two::doStuff() must be an instance of One, none
given, called in C:\workspace\LMS\cmd\test_container.php on line 41
and defined in C:\workspace\LMS\cmd\test_container.php on line 33
Catchable fatal error: Argument 1 passed to Two::doStuff() must be an instance of One, none
given, called in C:\workspace\LMS\cmd\test_container.php on line 41 and
defined in C:\workspace\LMS\cmd\test_container.php on line 33
または、メソッドではなくコンストラクターで機能する注入を示すより基本的な例...
class One {
function __construct(Two $two) {}
public function doStuff(Three $three) {}
}
class Two {}
class Three {}
$one = $container->make(One); // totally fine. Injection works
$one->doStuff(); // Throws Exception. (sad trombone)