警告:この質問はLaravel 4固有です。
コントローラーでFacadeを使用したことがあります。したがって、コードが機能していることがわかります。次に、さまざまな理由で依存性注入を導入する必要があります。
コントローラーをリファクタリングした後、次のエラーが表示されます。
Illuminate\Container\BindingResolutionException
[パラメーター#0 [$ name]]を解決できない解決できない依存関係。
問題がどこにあるのかわかりません。エラーメッセージは私には不可解であるように見えますが、理解できません。 (HelpersInterface
のバインディングを登録したので、__constructor
パラメーターに問題はありません)
コードの重要な部分は次のとおりです。
ファイル:app/start/global.php
<?php
// ...
App::bind('Acme\Interfaces\HelpersInterface', 'Acme\Services\Helpers');
ファイル:composer.json
// ...
"autoload": {
// ...
"psr-0": {
"Acme": "app/"
}
},
// ...
ファイル:app/Acme/Controllers/BaseController.php
<?php namespace Acme\Controllers;
use Carbon\Carbon;
use Controller;
use Illuminate\Foundation\Application as App;
use Illuminate\View\Factory as View;
use Acme\Interfaces\HelpersInterface as Helpers;
use Illuminate\Http\Response;
class BaseController extends Controller {
/**
* @var \Illuminate\Foundation\Application
*/
private $app;
/**
* @var \Carbon\Carbon
*/
private $carbon;
/**
* @var \Illuminate\View\Factory
*/
private $view;
/**
* @var \Acme\Interfaces\HelpersInterface
*/
private $helpers;
function __construct(App $app, Carbon $carbon, View $view, Helpers $helpers)
{
$this->app = $app;
$this->carbon = $carbon;
$this->view = $view;
$this->helpers = $helpers;
$lang = $this->app->getLocale();
$now = $this->carbon->now();
$this->view->share('lang', $lang);
$this->view->share('now', $now);
}
/**
* Missing Method
*
* Abort the app and return a 404 response
*
* @param array $parameters
* @return Response
*/
public function missingMethod($parameters = array())
{
return $this->helpers->force404();
}
}
ファイル:app/Acme/Services/Helpers.php
<?php namespace Acme\Services;
use Illuminate\Config\Repository as Config;
use Illuminate\Database\Connection as DB;
use Illuminate\Http\Request;
use Illuminate\Routing\Redirector as Redirect;
use Illuminate\Session\Store as Session;
use Illuminate\Support\Facades\Response;
use Illuminate\Translation\Translator as Lang;
use Illuminate\View\Factory as View;
use Acme\Interfaces\MockablyInterface;
use Monolog\Logger as Log;
class Helpers implements HelpersInterface {
// ...
public function __construct(
Config $config,
Lang $lang,
View $view,
MockablyInterface $mockably,
Log $log,
Request $request,
Session $session,
DB $db,
Redirect $redirect,
Response $response
) {
// ...
}
// ...
}
ファイル:app/Acme/Providers/HelpersServiceProvider.php
<?php namespace Acme\Providers;
use Illuminate\Support\ServiceProvider;
use Acme\Services\Helpers;
class HelpersServiceProvider extends ServiceProvider {
private $db;
private $defaultDbConnection;
protected function init()
{
$this->db = $this->app['db'];
$this->defaultDbConnection = $this->db->getDefaultConnection();
}
public function register()
{
$this->init();
$this->app->bind('helpers', function ()
{
return new Helpers(
$this->app['config'],
$this->app['translator'],
$this->app['view'],
$this->app['mockably'],
$this->app->make('log')->getMonolog(),
$this->app['request'],
$this->app['session.store'],
$this->db->connection($this->defaultDbConnection),
$this->app['redirect'],
$this->app['Illuminate\Support\Facades\Response']
);
});
}
Acme\Services\Helpers
コンストラクタは$name
パラメータですが、タイプヒントはありません。
LaravelのIoCは魔法ではありません。すべてのパラメーターに型のヒントを提供しない場合、IoCコンテナーには何を渡すかを知る方法がありません。
修正しました。依存性注入に関するすべてのチュートリアルでは、インターフェイスの具体的な実装を参照しているため、これを実行する方法だと思いました。 Joseph Silber's
答えは私を正しい軌道に乗せた。
秘Theは、以下に示すように、インターフェイスをServiceProvider
のバインディングにバインドすることです。そのようにLaravelはヘルパーサービスをインスタンス化する方法を知っています。
ファイル:app/start/global.php
<?php
// ...
App::bind('Acme\Interfaces\HelpersInterface', 'helpers');
私にとっては、走るだけの問題でした
php artisan optimize:clear