2

我是ZendFramework 2和整個DI創意的新手。ZF2:完成正確的依賴注入

以下是我需要實現:

  1. 創建延伸的單一AbstractModel
  2. 供應是AbstractModel使用DI與依賴關係(在我的學說實體管理器)
  3. 使用很多模型類的祖先類,只要我需要它們作爲普通類

爲了更好地解釋3.讓我們看看這個例子:

class Ancestor extends Parent { } 

在控制器,或任何地方的理想:

$ancestor = new Ancestor(); 
$ancestor->doStuffWithEntityManager(); 

Uppon初始化祖先一定已經知道注射的資源。

這甚至可能嗎?如果不使用它的默認形式,我可以通過一些服務管理器等初始化祖先,只要我不需要指定每個祖先。我需要告訴zend:將這個和那個注入到擴展/實現X的每個類中。

任何想法?

P.S .:正如我所說我很新,所以請指定配置/類文件,我必須添加每一個示例代碼。

回答

6

在我的架構中,我喜歡以下內容。第一:我創建一個服務:

class Module 
{ 
    public function getServiceConfig() 
    { 
     return array(
      'factories' => array(
       'my-service-name' => 'MyNamespace\Factory\MyServiceFactory' 
      ) 
     ); 
    } 
} 

然後我創建ServiceFactory。這將是所有依賴關係都將得到照顧的地步。

<?php 
namespace MyNamespace\Factory; 

use Zend\ServiceManager\ServiceLocatorInterface; 
use Zend\ServiceManager\FactoryInterface; 
use MyNamespace\Service\SomeService; 

class MyServiceFactory implements FactoryInterface 
{ 
    /** 
    * Create service 
    * 
    * @param ServiceLocatorInterface $serviceLocator 
    * @return \MyNamespace\Service\SomeService 
    */ 
    public function createService(ServiceLocatorInterface $serviceLocator) 
    { 
     $service = new SomeService(); 
     $service->setEntityManager($serviceLocator->get('Doctrine\ORM\EntityManager')); 
     return $service; 
    } 
} 

MyService-Class甚至可能具有morde依賴關係,在我的情況下,由於它們實現的接口會自動注入。你可以看到一個例子right here。然後,一個特定的EntityService將只需要一個定義類似於this example here的存儲庫的函數。我們也建議您閱讀Rob Allens introduction to ServiceManager Configuration Keys。仔細閱讀「初始化程序」部分,我想這是您的主要問題?

我希望這涵蓋你的問題。

+0

相當。我的實現(當前工作)是相似的。我註冊一個db服務並在其中定義一個'get($ class)'方法。然後我用我需要的模型類在控制器中調用服務的get方法。服務工廠創建一個實例並注入我指定的依賴關係。我不確定這是否是正確的DI,但我想這已經足夠了。 –

+0

@Sam你有任何解決循環依賴的案例嗎?例如在你的回答中,如果'Doctrine \ ORM \ EntityManager'需要一個'SomeService'的實例呢?會有一個永無止境的遞歸循環。 – binnyb

+0

@binnyb聽起來像不好的設計:)除了將依賴關係重構爲有意義的東西外,沒有其他解決方案。可能需要適當的examamples來幫助你。 – Sam

-1
class Parent { 
    private $em; 

    public function __construct(\Doctrine\ORM\EntityManager $em) { 
     $this->em = $em; 
    } 
} 

class Ancestor extends Parent { } 

// To use, create an EntityManager $em 

$ancestor = new Ancestor($em); 
$ancestor->doStuffWithEntityManager(); // Uses $this->em internally 

這就是所有依賴注入。另見http://fabien.potencier.org/article/11/what-is-dependency-injection

在此處查看獲取/創建ZF2中的EntityManager:http://samminds.com/2012/07/a-blog-application-part-1-working-with-doctrine-2-in-zend-framework-2/

從本質上講,從AbstractActionController擴展控制器,你可以這樣做:

$this->getServiceLocator()->get('Doctrine\ORM\EntityManager'); 
+0

如果文檔在現實世界中是可以理解的或可應用的,我就不會在這裏提問。 「以某種方式創建一個EntityManager $ em」正是我不知道該怎麼做的。 –

+0

好吧,我已經澄清它希望。 – aderuwe

+0

嗯,不,因爲你的代碼實際上不是DI。它只是創建一個對象並將實體管理器作爲參數傳遞給構造函數。除了我熟悉DI的想法之外,我不知道如何讓zf2使用它的配置來爲我完成所有繁重的工作。 –