Silex 控制器依赖注入

Silex Controller Dependency Injection

我正在尝试将依赖项注入到我的 Silex 控制器中,因为我需要在我的控制器中使用类型为 user 的对象并使用它来处理一些事情。

$app->mount("/users", new \MyApp\Controller\Provider\User($user));

我通过实现 ControllerProviderInterface 实现了控制器:

class User implements ControllerProviderInterface{
    protected $user;

    public function __construct($user){
        //...
    }

    public function connect(Application $app)
    {
        //...
    }
}

路由和方法都在控制器中设置。没有依赖注入一切正常。但是只要我编辑代码并添加注入,我就会得到以下错误:

Missing argument 1 for ...::__construct()

当我创建对象时,我将那个参数发送给它,但是不知何故 Silex 在没有传递任何参数的情况下使用构造函数创建了一个实例。

Silex 采用与您可能习惯或期望的不同的依赖注入方法。 Silex\Application 是在 Silex 应用程序的几乎任何上下文中都可用的依赖项注入容器。您使用 $app 注册您的依赖项,这些依赖项将通过 $app 在您可能需要的任何上下文中注入。这是您在您的情况下可能会做的事情的示例。

$app["user"] = function () {
    return new \MyApp\Service\User();
};

$app->mount("/users", new \MyApp\Controller\Provider\User());

...

class User implements ControllerProviderInterface
{
    public function connect(Application $app)
    {
        $controller = $app["controller_factory"];

        $controller->get("/{id}", array($this, "get"));

        return $controller;
    }

    public function get(Application $app, Request $request, $id)
    {
        $user = $app["user"];

        // Do stuff
    }
}

Silex 中的依赖注入是不同的,它需要一点时间来适应,但是一旦您适应了它,就会很愉快地使用它并且它非常高效。

这个接受的答案不是问题的答案。答案中描述的东西也不是依赖注入,也不是它的真正粗略形式。它更像是将 $app 硬编码到您的控制器中。

问题中的代码无需更改即可运行。 connect 函数和构造函数中的代码可能有助于找出您的问题所在。这不是挂载的调用,我确定。

另一种方法是使用 ServiceController 而不是 ControllerProvider。您可以通过这种方式实现更熟悉的依赖注入感觉。

$app->register(new Silex\Provider\ServiceControllerServiceProvider());

$app["user"] = function () {
    return new User();
};
$app["user.controller"] = function () use ($app) {
    return new UserController($app["user"]);
};

$app->get("/users/{id}", "user.controller:get");

...

class User implements UserInterface
{
    // ...
}

...

class UserController
{
    protected $user;

    public function __construct(UserInterface $user)
    {
        $this->user = $user;
    }

    public function get(Request $request, $id)
    {
        $this->user;

        // Do stuff
    }
}

参考:http://silex.sensiolabs.org/doc/providers/service_controller.html