Silex控制器依赖注入

时间:2015-11-01 23:46:29

标签: php api rest dependency-injection silex

我正在尝试为我的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)
    {
        //...
    }
}

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

  

缺少... :: __ construct()

的参数1

当我创建对象时,我将该参数发送给它,但不知何故,Silex在使用构造函数之前创建了一个实例而没有传递任何参数。

3 个答案:

答案 0 :(得分:4)

另一种方法是使用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

答案 1 :(得分:1)

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中的依赖注入是不同的,需要一点点习惯,但是一旦你对它感到满意,很高兴能够使用并且它非常有效。

答案 2 :(得分:0)

这个被接受的答案不是问题的答案。答案中描述的东西也不是依赖注入,或者是它的真实形式。它更像是Hardcoding $ app进入你的控制器。

问题中的代码应该无需更改即可运行。 connect函数和构造函数中的代码可能有助于弄清楚问题所在。它确实不是对mount的召唤。