我正在尝试使用新的PHP 5.4 Dependency Injection component找到一种方法来使用Symfony 2 traits。
长话短说(实际上不是那么短),我的项目已经解耦了所有拥有自己的特定构造函数的View类。每个View都可以使用零个或多个视图助手,这些助手被定义为特征:
trait TranslatorHelper
{
/**
* @var Translator
*/
protected $translator;
/**
* @param Translator $translator
*/
protected function setTranslator(Translator $translator)
{
$this->translator = $translator;
}
/**
* @param string $text
* @return string
*/
public function translate($text)
{
return $this->translator->translate($text);
}
}
-
class UserEditView extends AbstractView
{
use TranslatorHelper;
public function __construct(User $user, UserEditForm $form)
{
// ...
}
}
我希望在我的控制器renderView()
中有一个方法,它在渲染视图之前根据View类使用的所有特征执行setter注入:
class Controller
{
public function renderView(View $view)
{
// Check what traits are used by $view, and inject their dependencies
// {...}
// Then render the View
return $view->render();
}
}
有关如何使用DependencyInjection
组件执行此操作的任何想法吗?
主要问题显然是视图不会由DI容器创建,但可以在应用程序流中的任何位置创建。只有在它们被渲染之前,才需要注入依赖项。
最后一点:我没有与Symfony组件联系在一起。另一个DI容器上的任何导线也将受到赞赏。
答案 0 :(得分:6)
Symfony 3.3引入了自动服务的概念
您所要做的就是在特征中创建一个setter函数并添加@required
注释。
private $entityManager;
/**
* @required
* @param EntityManagerInterface $entityManager
*/
public function setEntityManager(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
}
答案 1 :(得分:5)
我认为这种特性并不意味着以这种方式用于做DI。在类似的场景中我会做的是在视图类中使用构造函数注入(甚至setter会很好,甚至可能更好的构造函数),它实现了直接注入所需服务的特性。
如果您考虑在应用程序执行之前静态定义类实现的特征,那么您实际上不需要检查特征来执行动态注入。在运行之前,您将了解所需的服务,只需将其视为具有某种具体方法的接口即可。