php - 如何在 Laravel 4 中执行构造函数注入(inject)依赖项?

标签 php laravel

我的团队喜欢构造函数注入(inject)依赖项的想法,因为它使 deps 在查看类时变得非常清晰。通过使用外观,我知道它们可以被模拟和交换,但是必须检查类的每一行以找出它所依赖的内容!我发现我可以使用例如 Form::getFacadeRoot() 找到外观背后的真正类。

我最终得到的 Controller 代码是:

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 ]].

我已经接近正确的轨道了吗?这是我边写边编造的,因为我没有看到关于这个问题的太多讨论。请随意评论我尝试的原因;不过,我可能会被卖掉。

谢谢!

最佳答案

您需要使用 Laravel 的 IoC 容器将类依赖项映射到类。这可以使用应用程序外观来完成。所以在上面的构造函数示例中

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

您将创建一个看起来类似于以下内容的绑定(bind):

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

Taylor Otwell 建议使用接口(interface)作为类依赖项的契约。因此,理想情况下,您完成的代码应如下所示(我在示例中对其进行了精简)。

对于您的 Controller :

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()
}

要注入(inject)的类:

use Namespace\For\FormInterface;

class MyFormClass implements FormInterface{

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

最后创建将所有内容组合在一起的绑定(bind):

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

这里发生的事情是,每次 Laravel 看到 Controller 中暗示的 FormInterface 类型的实例时,如果创建一个新的 myFormFunction() 并将其作为参数传递进来。通过使用接口(interface),它为您的类依赖项提供了一个需要遵循的契约,以确保它们可以轻松交换而不会导致错误。因此,假设您的团队后来开发了一个新的和改进的表单类,您只需更新您的绑定(bind),如下所示:

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

我强烈建议您研究一下服务提供商,因为它们提供了一种管理包和 IoC 绑定(bind)的绝佳方法。可以在这里找到一篇关于服务提供商的好文章:

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

您可以在此处阅读有关 Laravel 的 IoC 容器的更多信息:

http://laravel.com/docs/ioc

此外,如果您可以获得《从学徒到 artisan 》一书的副本。我强烈推荐阅读 Taylor Otwell 的《Laravel 4 高级应用程序架构》。它很容易理解,并且真正详细地介绍了管理依赖项注入(inject)。

希望有帮助。

关于php - 如何在 Laravel 4 中执行构造函数注入(inject)依赖项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17031998/

相关文章:

php - 运行 php shell_exec 而不向浏览器返回结果?

php - 检索 id 而不显示它

php - 在 PHP 中查找数组的子集

php - 带有图表的 Join 语句 Laravel

model - Laravel 模型获取类的实例

php - 无法在 laravel 的 Controller 中使用数据库事务(DB::beginTransaction)

php - 如何在 Laravel 中正确合并多个集合

php - 如何将 php 生成的图像传递到 html 元标记中

php - 尝试在 php 中实现(理解)Decorator 模式

php - Laravel Eloquent 加入奇怪的查询