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
我正在尝试将依赖项注入到我的 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