我想知道如何使用php(供学习)实现依赖注入容器。我得到了依赖注入的概念,我可以实现它,但我只能在php框架的控制器之前考虑因素。
意味着整个实例化、注入等都发生在控制器中。喜欢
class SampleController{
public function action1(){
$sample_object = new ObjectToInject();
$dependent_object = new DependentObject($sample_object);
$dependent_object->doSomething();
...
etc
}
}现在我要说的是,如果逻辑变得更加复杂,控制器就会膨胀。我知道我的控制器会变得臃肿,这不意味着它仍然无法维护吗?
问题:
如果我的问题含糊不清,请纠正我。谢谢
发布于 2014-03-05 01:34:02
这是个很有意义的问题。要快速回答你的观点:
(1) No.那是不对的。当你必须在某个地方做你的线路,它不应该在你的控制器里。您的控制器应该只接收完成其工作所需的完整对象。不要给他们超过他们需要的东西。示例:
示例
class UserController
{
public function __construct(UserRepository $UserRepository)
{
$this->UserRepository = $UserRepository;
}
public function showUser($id)
{
$User = $this->UserRepository->find($id);
}
}请注意,UserController只将UserRepository作为依赖项?同时,UserRepository可能如下所示:
class UserRepository
{
protected $registry = array();
public function __construct(UserFactory $UserFactory, UserMapper $UserMapper)
{
$this->UserFactory = $UserFactory;
$this->UserMapper = $UserMapper;
}
public function find($id)
{
if (isset($this->registry[$id]) {
return $this->registery[$id];
}
$User = $this->UserMapper>find($id);
$this->registry[$User->id] = $User;
return $User;
}
public function findOrNew($id)
{
if (!$User = $this->UserMapper->find($id)) {
$User = $this->UserFactory->make(array('id' => $id));
}
return $User;
}
}如果您的UserController不直接需要UserFactory或UserMapper对象,它应该不了解它们。此外,您的UserRepository不应该知道注入到UserMapper中的DataAccessLayer。UserMapper也不需要知道DataAccessLayer依赖于PDOConnection对象而不是其他东西。
(2)容器的使用是做在控制器中不应该做的事情:连接所有依赖项。了解DI容器是什么以及它是如何工作的最简单、最简单的方法是下载和使用Pimple。它是一个非常简单的、直截了当的DI容器,并且有很好的文档说明:https://github.com/fabpot/Pimple
(3),这是个大话题。Symfony是Pimple的一个更高级的版本。我建议学习Pimple,然后阅读Symfony的文档并查看它们使用的示例。还可以查看Laravel的,甚至PHP https://github.com/mnapoli/PHP-DI
(4)如前所述见Pimple:https://github.com/fabpot/Pimple
(5) --只要有需要测试的东西,就应该努力测试所有的代码逻辑。想必,应用程序中的每个方法/函数/类都执行操作,因此您应该测试它是否正在执行它应该做的事情。您不需要做的是测试它的任何依赖项是否正在执行他们应该做的事情,因为您大概是在测试这些依赖项。您相信传递给一个类或方法的数据已经过测试,然后只测试新的类/方法要做的事情。
但是,我再次强烈建议学习Pimple,然后尝试类似于PHP的东西,以了解自动反射和自动解析依赖关系是如何工作的。最好的方法就是让自己沉浸在各种各样的容器中,并与它们一起玩耍。
发布于 2014-03-05 08:59:11
实例化依赖关系不是“逻辑”,它只是配置。
AmgLauncher写了一个很好的答案,我想提供一个更简单的答案:控制器和服务没有什么不同。您应该对控制器使用依赖注入,就像对服务一样。
问题是: Symfony并不鼓励(至少通过他们的文档)。不要盲目地遵循Symfony的DIC文档。
最后,问题是:如果控制器有依赖项,那么谁来构造它呢?
这是集装箱的工作。容器将构建控制器和所有服务。问题是有些框架不是这样工作的。在Symfony 2中,有一个选项:作为服务的控制器。
如果要使用Pimple,则必须编写创建所有控制器的所有代码。那是无用的/无聊的代码。粉刺并不适合这种情况。
正如AgmLauncher所建议的,还可以看看PHP-DI,例如本指南介绍如何编写控制器。。我还建议您阅读这个关于什么是DI容器以及它是如何工作的的简单介绍。(免责声明:我是PHP的维护者)
https://stackoverflow.com/questions/22186642
复制相似问题