帮助MVC应用程序中的依赖注入

Cob*_*bby 9 php model-view-controller dependency-injection zend-framework doctrine-orm

Zend Framework/Doctrine 2应用程序:

/app
    /modules
        /blog
            /controllers
                /BlogController.php
            /domain
                /entities
                /services
                    /PostService.php
                /repositories
Run Code Online (Sandbox Code Playgroud)

PostService负责基本的CRUD操作,直接处理实体和EntityManager,以从我的控制器中抽象出业务和持久性逻辑.

如果可能的话,我想将我的服务作为POPO.在我的服务类中访问/注入EntityManager的最佳方法是什么?我是DI的新手,因此这个问题.EntityManager可作为控制器中的引导资源进行访问.

我应该只为服务编写一个抽象类来访问EntityManager吗?我应该编写一个类来实例化我的服务,通过构造函数/ setter注入EntityManager吗?...这将涉及我的服务的接口.我应该使用DI框架吗?如果是这样,哪一个又如何?

或者还有另一种更好的方法吗?

我已经完成了依赖注入的阅读,但在这种情况下仍然没有完全掌握它.


更新(2011年1月12日)

所以这是我当前的工作解决方案:我有一个名为Resource的动作帮助器,它是从引导程序检索资源的帮助程序,或者您可以手动向其添加资源:http://pastie.org/1450851

$this->_helper->Resource('em'); // get EntityManager
Run Code Online (Sandbox Code Playgroud)

有人可以提供一些深入了解在助手类中本地存储引导资源的性能影响吗?我过度了吗?
TODO:将resourcesMap重构出类.

我有一个用于加载服务的动作助手:http://pastie.org/1450855
TODO:在尝试加载服务之前添加检查.

请对以上内容提出一些批评:)

Bry*_* M. 5

为了使我的服务层与应用程序的其余部分分开,我将经常依靠我的控制器来处理注入.我还没有分解并使用DI容器,但这里描述的资源注入器非常适合在我的应用程序中传递EntityManager.

EntityManager在引导程序上作为资源实例化,如果控制器要求,ActionHelper会将其添加到控制器.然后我将使用构造函数注入或setter注入将它传递给服务对象.

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);
    } 
}
Run Code Online (Sandbox Code Playgroud)

我也使用一个名为的接口IHasEntityManager.

如果您不想让控制器负责构建Service对象,您可能需要查看像Symfony Dependency Injection这样的DI容器.