我正在尝试为我的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在使用构造函数之前创建了一个实例而没有传递任何参数。
答案 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的召唤。