Zend Framework和控制器注入解决了紧耦合问题

时间:2014-02-27 15:05:44

标签: php zend-framework dependency-injection zend-framework2

与ASP.NET MVC类似,我想在控制器及其依赖项上实现松散耦合。

我想实现以下目标:

class TimesheetController extends AbstractActionController
{    
    private $userRepository;

    function __Construct()
    {
        $sm = $this->getServiceLocator();
        $this->userRepository = $sm->get('Application\Model\Concrete\TGUserRepository');
    }

    // ... becomes

    function __Construct( IUserRepository $userRepo ) // the controller is injected with a bound repository so I do not have to implicitly specify it in the construct
    {
        $this->userRepository = $userRepo;
    }

    // And this is my action

    public function ListAction()
    {
        $users = $this->userRepository->Users();

        $view = new ViewModel( array( "Users" => $users ) );

            $secondarySidebarView = new ViewModel();
            $secondarySidebarView->setTemplate('something/poo');

        $view->addChild($secondarySidebarView, 'something');
        return $view;
    }

    // .... and more
}

我该怎么做?

我想可能会有一个绑定函数说当需要IUserRepository时,去制作一个TGUserRepository

Bind("IUserRepository", "TGUserRepository");

我见过Laravel完全按照我的意愿行事:

http://laravel.com/docs/ioc

1 个答案:

答案 0 :(得分:0)

控制器的调用方式与ZF2中的服务完全相同,因此当您在config / module.config.php中声明一个新控制器时,不是在'invokables'中注册它,而是可以在'factory'中注册它例如:

'controllers' => array(
    'invokables' => array(
        'Application\Controller\Index'          => 'Application\Controller\IndexController',
    ),
    'factories' => array(
        'Application\Controller\Timesheet' => function ($sm) {
             $userRepository = $sm->get('Application\Model\Concrete\TGUserRepository');
             $controller = new \Application\Controller\TimesheetController($userRepository);
             $controller->setServiceLocator($sm);
             return $controller;
        },
    ),
),

顺便说一下,当您使用服务定位器来获取实例和服务时,您只能限制与ServiceLocator的耦合,您可以在测试中轻松“模拟”服务,或者由另一个服务替换服务来完成工作。

当然,随着应用程序的增长,ServiceLocator成为一大堆服务和实例。我变得不那么可读,很难知道'你在里面有什么'。通过在控制器中准确传递您所期望的(并且是必需的),我理解您的观点。