Инъекция зависимостей ZF2 в объекты контроллера без сервисного локатора

Я изучал компонент ZF2 Service Locator и могу сказать, что я понимаю, как он используется. У меня, однако, есть вопрос, который я считаю глупым, но задавать его не мешало бы.

Я хочу иметь пространство имен внутри моего модуля с именем Component, где я могу поместить общий код, например, в FunctionsComponent.php, MailerComponent.php или ExcelComponent.php. Это позволило бы мне делать некоторые вещи внутри моих контроллеров.

То, что я хотел бы попробовать, это иметь возможность иметь контроллеры, определяющие компоненты, которые они заинтересованы использовать (см. Ниже):

class SalesController extends AbstractController
{
protected $components = ['Excel'];

//In some action
public function exportAction()
{
$data = ['data to be exported'];
/**
$data : data to be exported
boolean : Whether to force download or save the file in a dedicated location
*/
$this->Excel->export($data, true);
}
}

Идея состоит в том, чтобы создать ComponentCollection, которая, возможно, реализует FactoryInterface или ServiceLocatorInterface, а затем позволить ему проверять каждый контроллер, когда MvcEvent был запущен внутри моего класса Module, и чтобы ComponentCollection вставляла все компоненты контроллера и делала их доступными без использования локатора службы как показано ниже:

$excel = $sm->get('Application\Component\Excel');

Я хорошо знаю, что это может показаться сложной задачей, но я чувствую, что лучший способ изучить структуру среди прочего — это поиграть с ней и попытаться сделать невообразимое.

0

Решение

Вы должны создать BaseController где-то, а затем расширить все ваши Controllers от BaseController, Затем вы можете ввести свои зависимости в вашем BaseController и использовать в любом месте у детей. Например, я делаю это в моем Controller установить заголовок заголовка:

<?php

namespace Application\Controller;

use Zend\Mvc\Controller\AbstractActionController;

class BaseController extends AbstractActionController
{

/**
* Sets the head title for every page
*
* @param string $title
*/
public function setHeadTitle($title)
{
$viewHelperManager = $this->getServiceLocator()->get('ViewHelperManager');
// Getting the headTitle helper from the view helper manager
$headTitleHelper = $viewHelperManager->get('headTitle');

// Setting a separator string for segments
$headTitleHelper->setSeparator(' - ');

// Setting the action, controller, module and site name as title segments
$siteName = 'Ribbon Cutters';
$translator = $this->getServiceLocator()->get('translator');
$title = $translator->translate($title);
$headTitleHelper->append(ucfirst($title));
$headTitleHelper->append($siteName);
}

}

Вместо определения методов вы можете определить свойства.

public $headTitleHelper

и назначить его в конструкторе BaseController

$this->headTitleHelper = $this->getServiceLocator()->get('ViewHelperManager')->get('headTitle');

Теперь вы можете использовать $this->headTitleHelper в детских контроллерах.

А потом

<?php

namespace Application\Controller;

use Zend\View\Model\ViewModel;
use Application\Controller\BaseController;

class IndexController extends BaseController
{

/**
* Property for setting entity manager of doctrine
*/
protected $em;

/**
* landing page
*
* @return ViewModel
*/
public function indexAction()
{

$this->setHeadTitle('Welcome');  // Welcome - Ribbon Cutters

$viewModel = new ViewModel();

return $viewModel;
}



/**
* Sets and gives Doctrine Entity Manager
*
* @return Doctrine Entity Manager
*/
protected function getEntityManager()
{
if (null === $this->em) {
$this->em = $this->getServiceLocator()->get('doctrine.entitymanager.orm_default');
}
return $this->em;
}
}

Я думаю, что это может помочь вам.

1

Другие решения

Я изучал компонент ZF2 Service Locator и могу сказать, что я понимаю, как он используется. У меня, однако, есть вопрос, который я считаю глупым, но задавать его не мешало бы.

Я хочу иметь пространство имен внутри моего модуля с именем Component, где я могу поместить общий код, например, в FunctionsComponent.php, MailerComponent.php или ExcelComponent.php. Это позволило бы мне делать некоторые вещи внутри моих контроллеров.

То, что я хотел бы попробовать, это иметь возможность иметь контроллеры, определяющие компоненты, которые они заинтересованы использовать (см. Ниже):

class SalesController extends AbstractController
{
protected $components = ['Excel'];

//In some action
public function exportAction()
{
$data = ['data to be exported'];
/**
$data : data to be exported
boolean : Whether to force download or save the file in a dedicated location
*/
$this->Excel->export($data, true);
}
}

Идея состоит в том, чтобы создать ComponentCollection, которая, возможно, реализует FactoryInterface или ServiceLocatorInterface, а затем позволить ему проверять каждый контроллер, когда MvcEvent был запущен внутри моего класса Module, и чтобы ComponentCollection вставляла все компоненты контроллера и делала их доступными без использования локатора службы как показано ниже:

$excel = $sm->get('Application\Component\Excel');

Я хорошо знаю, что это может показаться сложной задачей, но я чувствую, что лучший способ изучить структуру среди прочего — это поиграть с ней и попытаться сделать невообразимое.

0

Вы должны создать BaseController где-то, а затем расширить все ваши Controllers от BaseController, Затем вы можете ввести свои зависимости в вашем BaseController и использовать в любом месте у детей. Например, я делаю это в моем Controller установить заголовок заголовка:

<?php

namespace Application\Controller;

use Zend\Mvc\Controller\AbstractActionController;

class BaseController extends AbstractActionController
{

/**
* Sets the head title for every page
*
* @param string $title
*/
public function setHeadTitle($title)
{
$viewHelperManager = $this->getServiceLocator()->get('ViewHelperManager');
// Getting the headTitle helper from the view helper manager
$headTitleHelper = $viewHelperManager->get('headTitle');

// Setting a separator string for segments
$headTitleHelper->setSeparator(' - ');

// Setting the action, controller, module and site name as title segments
$siteName = 'Ribbon Cutters';
$translator = $this->getServiceLocator()->get('translator');
$title = $translator->translate($title);
$headTitleHelper->append(ucfirst($title));
$headTitleHelper->append($siteName);
}

}

Вместо определения методов вы можете определить свойства.

public $headTitleHelper

и назначить его в конструкторе BaseController

$this->headTitleHelper = $this->getServiceLocator()->get('ViewHelperManager')->get('headTitle');

Теперь вы можете использовать $this->headTitleHelper в детских контроллерах.

А потом

<?php

namespace Application\Controller;

use Zend\View\Model\ViewModel;
use Application\Controller\BaseController;

class IndexController extends BaseController
{

/**
* Property for setting entity manager of doctrine
*/
protected $em;

/**
* landing page
*
* @return ViewModel
*/
public function indexAction()
{

$this->setHeadTitle('Welcome');  // Welcome - Ribbon Cutters

$viewModel = new ViewModel();

return $viewModel;
}



/**
* Sets and gives Doctrine Entity Manager
*
* @return Doctrine Entity Manager
*/
protected function getEntityManager()
{
if (null === $this->em) {
$this->em = $this->getServiceLocator()->get('doctrine.entitymanager.orm_default');
}
return $this->em;
}
}

Я думаю, что это может помочь вам.

active «data-shortcut =» A
самый старый «data-shortcut =» O
голосует «data-shortcut =» V
1
По вопросам рекламы [email protected]