2014-11-07 2 views
1

В моем конфигурационном файле модуля у меня есть эти строки, которые загружают библиотеки и модели в ServiceManager, чтобы я мог их получить в контроллерах. Вы можете видеть, что все мои модели требуют такой же зависимости. Могу ли я спросить, как я могу вводить их без этих повторяющихся блоков кода? Это выглядит неправильно, но я не знаю, как я запускаю те же строки кода для разных библиотек. Или я вообще должен использовать фабрики? Спасибо!ZF2 - Загрузка моделей в Service Manager

'service_manager' => array(
    'abstract_factories' => array(
     'Zend\Cache\Service\StorageCacheAbstractServiceFactory', 
     'Zend\Log\LoggerAbstractServiceFactory', 
    ), 
    'aliases' => array(
     'translator' => 'MvcTranslator', 
    ), 
    'factories' => array(
     // Models 
     'Application\Model\Photo' => function($serviceLocator) { 
      $coreLibrary = $serviceLocator->get('Project\CoreLibrary'); 
      $io = $serviceLocator->get('Project\IO'); 
      $class = new Application\Model\Photo($coreLibrary, $io); 
      return $class; 
     }, 
     'Application\Model\Album' => function($serviceLocator) { 
      $coreLibrary = $serviceLocator->get('Project\CoreLibrary'); 
      $io = $serviceLocator->get('Project\IO'); 
      $class = new Application\Model\Album($coreLibrary, $io); 
      return $class; 
     }, 
     'Application\Model\Tag' => function($serviceLocator) { 
      $coreLibrary = $serviceLocator->get('Project\CoreLibrary'); 
      $io = $serviceLocator->get('Project\IO'); 
      $class = new Application\Model\Tag($coreLibrary, $io); 
      return $class; 
     }, 
     'Application\Model\User' => function($serviceLocator) { 
      $coreLibrary = $serviceLocator->get('Project\CoreLibrary'); 
      $io = $serviceLocator->get('Project\IO'); 
      $class = new Application\Model\User($coreLibrary, $io); 
      return $class; 
     }, 
     'Application\Model\Message' => function($serviceLocator) { 
      $coreLibrary = $serviceLocator->get('Project\CoreLibrary'); 
      $io = $serviceLocator->get('Project\IO'); 
      $class = new Application\Model\Message($coreLibrary, $io); 
      return $class; 
     }, 
    ), 
), 

ответ

2

Вы должны рассмотреть возможность использования AbstractFactory в этом случае. Смотрите код ниже:

namespace Application\Model; 
use Zend\ServiceManager\AbstractFactoryInterface; 
use Zend\ServiceManager\ServiceLocatorInterface; 

class AbstractModelFactory implements AbstractFactoryInterface 
{ 
    public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) 
    { 
     $requestedName = explode('\\', $requestedName); 

     if ((!isset($requestedName[0]) || $requestedName[0] != 'Application') 
      || (!isset($requestedName[1]) || $requestedName[1] != 'Model')) 
     { 
      return false; 
     } 

     $modelName = $requestedName[2]; 
     return class_exists('Application\Model\\'.$modelName); 
    } 

    public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) 
    { 
     $requestedName = explode('\\', $requestedName); 
     $modelName = $requestedName[2]; 

     $coreLibrary = $serviceLocator->get('Project\CoreLibrary'); 
     $io = $serviceLocator->get('Project\IO'); 
     $class = 'Application\Model\\'.$modelName; 
     return new $class($coreLibrary, $io); 
    } 
} 

Затем зарегистрировать свой завод, как так:

'service_manager' => [ 
    'abstract_factories' => [ 
     'Application\Model\AbstractModelFactory' 
    ] 
] 
1

Вы также могли бы использовать Инициализаторы:

public function getServiceConfig(){ 
    return array(
     'initializers' => array(
      function ($instance, $sm) { 
       if($instance instanceof Model\CoreAndIOAwareInterface){ 
        $coreLibrary = $serviceLocator->get('Project\CoreLibrary'); 
        $io = $serviceLocator->get('Project\IO'); 
        $instance->setCoreLibrary($coreLibrary); 
        $instance->setIO($io); 
       } 
      }, 
     ) 
    ); 
} 

так, то Вы должны создать интерфейс также:

interface CoreAndIOAwareInterface 
{ 
    public function setCoreLibrary(CoreLibrary $coreLibrary); 
    public function setIO(IO $io); 
} 

и имплементация ts этот интерфейс в ваших классах моделей. Это зависит от вас, как это сделать. На мой взгляд, лучший способ - создать абстрактный класс, а затем расширить его с помощью конкретного класса.

Смежные вопросы