[英]how to implement dependency injection container and dependency injection
我想知道如何使用php(研究)實現依賴項注入容器。 我得到了依賴注入的概念,我可以實現它,但是我只能分解到php框架的控制器為止。
這意味着整個實例化,注入等都發生在控制器中。 喜歡
class SampleController{
public function action1(){
$sample_object = new ObjectToInject();
$dependent_object = new DependentObject($sample_object);
$dependent_object->doSomething();
...
etc
}
}
現在我要說的是,如果邏輯變得更加復雜,則控制器會變得腫。 我知道我的控制器變得腫,是不是意味着它仍然不太容易維護?
問題:
如果我的問題含糊,請糾正我。 謝謝
這是一個真正的問題。 要快速回答您的觀點:
(1)不。那是不正確的。 盡管必須在某處進行布線,但不應在控制器中進行布線。 您的控制器應該只接收完成工作所需的完全構建的對象。 不要給他們超過他們需要的東西。 例:
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-DI https://github.com/mnapoli/PHP-DI
(4)像以前一樣看到Pimple: https : //github.com/fabpot/Pimple
(5)只要有要測試的內容,就應該努力測試所有代碼邏輯。 大概,應用程序中的每個方法/函數/類都可以執行某項操作 ,因此您應該測試它是否在執行應執行的操作。 您不必做的就是測試它的任何依賴項是否在執行應做的事情,因為您大概正在測試那些依賴項。 您相信傳遞給一個類或方法的數據已經過測試,然后僅測試新類/方法的作用。
但是,我再次強烈建議您學習Pimple,然后嘗試使用PHP-DI之類的工具來查看自動反射和自動解析依賴項的工作方式。 最好的方法就是將自己浸入各種容器中並隨身攜帶。
實例化依賴關系不是“邏輯”,而只是配置。
AmgLauncher寫了一個很好的答案,我想提供一個簡單的答案:控制器與服務沒有什么不同。 您應該在控制器上使用依賴注入,就像服務一樣。
這是問題所在:Symfony不鼓勵這樣做(至少通過他們的文檔)。 不要盲目遵循Symfony的DIC文檔。
所以最后,問題是: 但是如果控制器具有依賴項,那么將由誰/誰來構造我的控制器?
這就是容器的工作。 該容器將構建您的控制器和所有服務。 問題是某些框架不能那樣工作。 在Symfony 2中,有一個選項: 控制器即服務 。
如果要使用Pimple,則必須編寫創建所有控制器的所有代碼。 那是無用/無聊的代碼。 丘疹並不真的適合。
正如AgmLauncher所建議的那樣,還要看看PHP-DI ,例如, 有關如何編寫控制器的指南 。 我還建議您閱讀什么是DI容器及其工作原理的簡單介紹。 (免責聲明:我是PHP-DI的維護者)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.