문제

Zend Framework/Doctrine 2 application.:

/app
    /modules
        /blog
            /controllers
                /BlogController.php
            /domain
                /entities
                /services
                    /PostService.php
                /repositories

PostService is responsible for basic CRUD opterations, dealing directly with entities and the EntityManager to abstract the business and persistence logic out of my controllers.

If possible, I would like to keep my services as POPOs. What's the best way to access/inject the EntityManager in my service class? I'm new to DI, hence this question. The EntityManager is accessible as a bootstrap resource in my controllers.

Should I just write a abstract class for services to access the EntityManager? Should I write a class to instantiate my services, injecting the EntityManager via the constructor/setter?... which would involve an interface for my services. Should I use a DI framework? If so, which one and how?

Or is there another, better way to do this?

I have done reading on dependency injection but still don't fully grasp it in this context.


Update (12th Jan 2011)

So this is my current working solution: I have an action helper called Resource, it is a helper for retrieving resources from the bootstrap, or you can manually added resources to it: http://pastie.org/1450851

$this->_helper->Resource('em'); // get EntityManager

Can someone please provide some insight into the performance impact of storing bootstrap resources locally within the helper class? Am I over doing it?
TODO: Refactor the resourcesMap out of the class.

And I have an action helper for loading services: http://pastie.org/1450855
TODO: Add checks before attempting to load the service.

Please provide some criticism on the above :)

도움이 되었습니까?

해결책

To keep my service layer separated from the rest of the application, I will often rely on my controllers to handle the injection. I have yet to break down and use a DI container, but the resource injector described here works perfect for passing the EntityManager around my application.

The EntityManager is instantiated on the bootstrap as a resource, and an ActionHelper will add it to the controller if the controller is asking for it. Then I'll pass it to service objects either using constructor injection or setter injection.

class MyController extends Zend_Action_Controller
{
    // A little different from O'Phinney's implementation. I'm adding
    // the resource named 'entitymanager' as the public property $em.
    public $dependencies = array(
      'entitymanager' => 'em'
    );

    public function myAction()
    {
       $service = new MyService($this->em);
       // or...
       $service = new MyService();
       $service->setEntityManager($em);
    } 
}

I do use an interface called IHasEntityManager as well.

If you don't want to make your controller responsible for building Service objects, you may want to look into a DI container like Symfony Dependency Injection.

다른 팁

Ben Scholzen (@DASPRiD) has an example of a his own DI pseudo-framework in the source-code for his blog. He uses custom mappers for his persistence, which he passes to each service on service instantiation. But it seems like it would be easily modifiable to accept the Doctrine2 EntityManager instance instead.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top