2012-10-25 16 views
6

Tôi gặp vấn đề. Tôi cố gắng để có được Entity-Manager mà không có một Controller, nhưng tôi không tìm được cách nào. Tại thời điểm này, tôi nhận được Trình quản lý thực thể như sau:ZF2 và EntityManager (Doctrine)

(Controller) 
public function getEntityManager() 
{ 
    if (null === $this->_em) { 
     $this->_em = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager'); 
    } 
    return $this->_em; 
} 

(Plugin) 
public function getEntityManager() 
{ 
    if($this->_em == null){ 
     $this->_em = $this->getController()->getServiceLocator()->get('doctrine.entitymanager.orm_default'); 
    } 
    return $this->_em; 
} 

Bạn thấy đấy, tôi cần allways một bộ điều khiển. Nhưng, nếu tôi cần EntityManager trong một mô hình, tôi có một vấn đề. Tôi có thể cung cấp cho các mô hình điều khiển, nhưng tôi nghĩ rằng đây thực sự là một cách xấu.

Bạn có ý tưởng nào để lấy EntityManager mà không cần bộ điều khiển không?

Trả lời

7

Con đường tôi xử lý thuyết là thông qua Dịch vụ, tôi làm điều đó như sau:

//some Controller 
public function someAction() 
{ 
    $service = $this->getServiceLocator()->get('my_entity_service'); 
    return new ViewModel(array(
     'entities' => $service->findAll() 
    )); 
} 

Các Service->findAll() sẽ giống như thế này:

public function findAll() 
{ 
    return $this->getEntityRepository()->findAll(); 
} 

Bây giờ chúng ta cần phải xác định my_entity_service. Tôi làm điều này bên trong của tôi Module.php

public function getServiceConfig() 
{ 
    return array(
     'factories' => array(
      'my_entity_service' => 'Namespace\Factory\MyServiceFactory' 
     ) 
    ); 
} 

Tiếp theo tôi tạo máy (lưu ý: điều này cũng có thể được thực hiện thông qua chức năng ẩn danh bên trong Module.php)

<?php 
namespace Namespace\Factory; 

use Zend\ServiceManager\ServiceLocatorInterface; 
use Zend\ServiceManager\FactoryInterface; 
use Namespace\Model\MyModel; 

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

     return $myModel; 
    }  
} 

Bây giờ đây là rất nhiều để nhai: DI hoàn toàn hiểu được điều đó. Điều gì đang xảy ra ở đây thực sự là rất đơn giản. Thay vì tạo mô hình của bạn và bằng cách nào đó vào EntityManager, bạn gọi ServiceManager của ZF2 để tạo Mô hình cho bạn và tiêm EntityManager vào nó.

Nếu điều này vẫn còn khó hiểu với bạn, tôi sẽ sẵn sàng cố gắng giải thích bản thân mình tốt hơn. Để làm rõ thêm, tuy nhiên tôi muốn biết về trường hợp sử dụng của bạn. I.e: bạn cần EntityManager nào hoặc bạn cần nó ở đâu.

dụ Mã này nằm ngoài phạm vi câu hỏi

Chỉ cần để cung cấp cho bạn một ví dụ sống của một cái gì đó tôi làm qua ServiceFactories với các hình thức:

public function createService(ServiceLocatorInterface $serviceLocator) 
{ 
    $form = new ReferenzwertForm(); 
    $form->setHydrator(new DoctrineEntity($serviceLocator->get('Doctrine\ORM\EntityManager'))) 
     ->setObject(new Referenzwert()) 
     ->setInputFilter(new ReferenzwertFilter()) 
     ->setAttribute('method', 'post'); 

    return $form; 
} 
4

câu hỏi thực sự của bạn là "Làm thế nào để có được một bản sao của ServiceManager trong các lớp học của tôi "

Đối với điều này, hãy xem docu: (dưới cùng của trang http://zf2.readthedocs.org/en/latest/modules/zend.service-manager.quick-start.html)

Theo mặc định, Zend Framework MVC đăng ký một initializer sẽ tiêm dụ ServiceManager, đó là một thực hiện Zend \ ServiceManager \ ServiceLocatorInterface, vào bất kỳ lớp thực hiện Zend \ ServiceManager \ ServiceLocatorAwareInterface. A thực hiện đơn giản trông giống như sau.

để implent các ServiceLocatorInterface trong lớp học của bạn và sau đó bên trong lớp của bạn, bạn có thể gọi:

$this->getServiceLocator()->get('doctrine.entitymanager.orm_default'); 

hoặc bất kỳ dịch vụ khác mà bạn đã đăng ký.