2

私のチームは、コンストラクターによって注入された依存関係のアイデアを気に入っています。これは、クラスを見るときに deps が非常に明確になるためです。ファサードを使用すると、それらを嘲笑したりswapペディングしたりできることはわかっていますが、クラスのすべての行を調べて、それが何に依存しているかを把握する必要があります! たとえば、ファサードの背後にある真のクラスを見つけることができることを発見しましたForm::getFacadeRoot()

私が最終的に得たコントローラーコードは次のとおりです。

use Illuminate\Html\FormBuilder as Form;
use Illuminate\Validation\Factory as Validator;
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage as Session;
use Illuminate\Http\Request as Input;
use Illuminate\Routing\Redirector as Redirect;
use Illuminate\View\Environment as View;

class HomeController extends BaseController {

    protected $form;
    protected $validator;
    protected $session;
    protected $input;
    protected $redirect;
    protected $view;

    protected $layout = 'layouts.master';

    protected $validationRules = array(
        'name'  => array('required', 'min:3'),
        'email' => array('required', 'regex:/^.+@.+\..{2,4}$/')
    );

    public function __construct(Form $form, Validator $validator, Session $session,
        Input $input, Redirector $redirect, View $view
    ) {
        $this->form      = $form;
        $this->validator = $validator;
        $this->session   = $session;
        $this->input     = $input;
        $this->redirect  = $redirect;
        $this->view      = $view;
    }

        ...
}

私のテストが実行$this->client->request('Get', '/');されると、エラーが発生します:

Illuminate\Container\BindingResolutionException: Unresolvable dependency resolving [Parameter #2 [ <required> $csrfToken ]].

私はここで正しい道に近づいていますか?この問題についてはあまり議論されていないので、私はこれを作りながら考えています。試してみる理由について、気軽にコメントしてください。私はまだファサードで販売される可能性があります。

ありがとう !

4

2 に答える 2

7

Laravel の IoC コンテナーを使用して、クラスの依存関係をクラスにマップする必要があります。これは、App ファサードを使用して実行できます。したがって、上記のコンストラクターの例では

public function __construct(Form $form, Validator $validator, Session $session, Input $input, Redirector $redirect, View $view)

次のようなバインディングを作成します。

App::bind('Form', function(){
    return new Illuminate\Html\FormBuilder()
});

Taylor Otwell は、インターフェイスをクラスの依存関係のコントラクトとして使用することを推奨しています。理想的には、完成したコードは次のようになります (例のために少しスリム化しました)。

コントローラーの場合:

use Namespace\For\FormInterface;

class HomeController extends BaseController {

    public function __construct(FormInterface $form)
    {
        $this->form = $form;
    }

    public function myHomePage()
    {
        $this->form->myFormFunction()
    }
}

インターフェイスの場合:

namespace Namespace\For;

interface FormInterface(){

    public function myFormFunction()
}

注入するクラス:

use Namespace\For\FormInterface;

class MyFormClass implements FormInterface{

    public function myFormFunction()
    {
        // Do some stuff here
    }
}

そして最後に、すべてをまとめるバインディングを作成します。

App::bind('Namespace\For\FormInterface', function()
{
    return new MyFormClass();
});

ここで起こっているのは、Laravel がFormInterfaceコントローラーでヒントされた型のインスタンスを参照するたびに、新しいmyFormFunction()ものを作成してそれをパラメーターとして渡すことです。インターフェースを使用することで、クラスの依存関係が従うべきコントラクトを提供し、エラーを引き起こすことなく簡単に交換できるようにします。したがって、チームが後で新しい改良されたフォーム クラスを開発したとします。次のようにバインディングを更新するだけです。

App::bind('Namespace\For\FormInterface', function()
{
    return new  MyNewFormClass();
});

パッケージと IoC バインディングを管理する優れた方法を提供するサービス プロバイダーを検討することを強くお勧めします。サービス プロバイダーに関する優れた記事は、次の場所にあります。

http://fideloper.com/laravel-4-where-to-put-bindings

Laravel の IoC コンテナの詳細については、こちらをご覧ください。

http://laravel.com/docs/ioc

さらに、「見習いから職人へ」という本のコピーを手に入れることができれば。Advanced Application Architecture With Laravel 4, by Taylor Otwell を読むことを強くお勧めします。従うのは簡単で、依存性注入の管理について詳しく説明しています。

それが役立つことを願っています。

于 2013-10-12T09:04:43.883 に答える
2

このルートを選択すると、読みやすさがかなり犠牲になると思います。

最終的に、依存性注入は、テスト容易性を可能にするための単なるパターンです。ファサードはインジェクションなしで簡単にテストできるので、これを行う価値はあまりありません...

于 2013-06-10T20:52:22.313 に答える