DI对象方法


DI object method

如何在一些对象方法而不是构造函数中注入依赖项?

以下示例适用于__constructor注入

如何在indexAction中注入DateTime对象?

app.php

 $app['index.controller'] = $app->share(function() use ($app) {
       return new Controllers'IndexController(new 'DateTime());
     });

IndexController.php

namespace Moo'Controllers;
class IndexController
{
  private $date;
  public function __construct('DateTime $date)
  {
    $this->date = $date;
  }
  public function indexAction()
  {
   return $this->date->format('y-m-d');
  }
}

如果您的类根据调用的方法有不同的依赖项,那么这些方法可能应该在单独的类中定义。

对于控制器,我认为规则很简单。操作方法所需的依赖项应该通过构造函数传递。请求附带的任何内容都应该作为方法参数。

我不确定你要注入什么样的依赖关系如果它们只是服务,那么您应该将控制器拆分为多个类大量的构造函数参数是一种代码气味。你关心它是好事,但你试图用错误的方式解决它。

如果依赖项随请求而来,则应将其注入控制器方法(操作)控制器方法应该接受请求并返回响应

所有路由占位符都会自动注册为请求属性。因此,如果你的约会来自一个请求:

$app->get('/my/path/{date}', 'index.controller:indexAction');

它将作为请求属性提供:

public function indexAction(Request $request)
{
    $request->attributes->get('date');
}

任何请求属性都可以直接注入控制器:

public function indexAction($date)
{
}

这也意味着,如果手动设置请求属性,就可以将其注入控制器。按名称匹配:

// somewhere in your code (event perhaps)
$request->attributes->set('myDate', new 'DateTime());
// in your controller
public function indexAction('DateTime $myDate)
{
}

最后,您可以使用路由变量转换器将请求附带的简单类型转换为更复杂的类型。

$callback = function ($post, Request $request) {
    return new Post($request->attributes->get('slug'));
};
$app->get('/blog/{id}/{slug}', 'your.controller:indexAction')
    ->convert('post', $callback);

阅读文档了解更多信息。

只是为了记录,因为你可能不想这样做,事实上,可以通过使用extend方法在Silex中进行方法注入(事实上,它是负责注入的Pimple容器):

<?php
$app['some_service'] = $app->share(function() use ($app) {
  return SomeClass($app['some_dependency']);
});
$app['some_service'] = $app->extend('some_service', function($instance, $app) {
   $instance->setSomeDependency($app['another_dependency']);
   return $instance;
});

话虽如此,你应该考虑@JakubZalas的解释,因为你不想在extend方法中调用控制器操作(你想被调度器调用)。