2013-11-18 2 views
2

Я создаю сайт интрасети с помощью frontcontroller, который вытаскивает информацию из запрошенного приложения из репозитория и выполняет этот субконтроллер. У меня есть проблема: каждое приложение может использовать разные службы с разными параметрами конфигурации, и мне нужно передать эти службы в субконтроллер, не пахнув кодом субконтроллера с конфигурационными материалами. Глядя на приведенный ниже пример, я пытаюсь использовать DI, чтобы передать все, что подходит для нескольких сервисов, общих для всех приложений, но когда у меня много разных сервисов, которые не являются общими для всех приложений, он становится беспорядком конструктора. Поскольку субконтроллеры создаются динамически, я не могу просто передать только зависимости, необходимые для каждого отдельного контроллера.PHP Ввод различных зависимостей в субконтроллеры

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

$appRepository = new AppRepository('username_1', 'password_1', 'etc_1'); 
$userRepository = new UserRepository('username_2', 'password_2', 'etc_2'); 

// misc services used by apps 
$barrinator = new Barrinator('bar_params'); 
$bazzinator = new Bazzinator('baz_params'); 

// example 
$params['app_id'] = 'foo'; 
$params['user_id'] = 'bob'; 

$frontController = new FrontController($appRepository, $userRepository); 
$frontController->execute($params); 

class FrontController 
{ 
    protected $appRepository = null; 
    protected $userRepository = null; 

    public function __construct(AppRepositoryInterface $appRepository, UserRepositoryInterface $userRepository) 
    { 
     $this->appRepository = $appRepository; 
     $this->userRepository = $userRepository; 
    } 

    public function execute($params) 
    { 
     $app = $this->appRepository->get($params['app_id']); 
     $appController = $app->getControllerName(); 
     $controller = new $appController($this->userRepository); 
     $controller->execute($params); 
    } 
} 

abstract class AppAbstract 
{ 
    protected $userRepository = null; 

    public function __construct(UserRepositoryInterface $userRepository) 
    { 
     $this->userRepository = $userRepository; 
    } 

    abstract public function execute($params); 
} 

class Foo extends AppAbstract 
{ 
    public function execute($params) 
    { 
     $user = $this->userRepository->get($params['user_id']); 
     // etc. 
    } 
} 

class Bar extends AppAbstract 
{ 
    public function execute($params) 
    { 
     // halp! how to get barrinator resource 
     $bar = $barrinator->get($params['bar_id']); 
    } 
} 

ответ

1

Похоже, что вы можете использовать некоторую помощь от контейнера DI.

Роль контейнера заключается в построении графов объектов. То есть контейнер может создавать ваши контроллеры и автоматически вводить их зависимости.

Фронт-контроллер будет выглядеть:

class FrontController 
{ 
    protected $container; 

    public function __construct(Container $container) 
    { 
     $this->container = $container; 
    } 

    public function execute($params) 
    { 
     $app = $this->appRepository->get($params['app_id']); 
     $appController = $app->getControllerName(); 
     $controller = $this->container->get($appController); 
     $controller->execute($params); 
    } 
} 

Я biaised предложить контейнер (я разрабатываю PHP-DI), а вот список контейнеров: https://gist.github.com/mnapoli/6159681

+0

Так Мне в основном нужно иметь какой-то конфигурационный список где-то из субконтроллеров и их зависимостей и использовать другой слой, например DIC, для создания и инъекции? – fwrawx

+0

@fwrawx Да, хотя некоторые контейнеры используют отражение, чтобы избежать необходимости писать конфигурацию. См. Здесь, например: http://php-di.org/doc/definition –

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