我正在构建一个带有前控制器的Intranet站点,该控制器将从存储库中提取所请求的应用程序信息并执行该子控制器。我遇到的问题是每个应用程序都可以使用具有不同配置参数的不同服务,我需要将这些服务传递给子控制器,而不会使用配置内容来掩盖子控制器的代码。看看下面的例子,我尝试使用DI来传递所有应用程序通用的一些服务,但是当我有许多不同于所有应用程序的服务时,它会变成构造函数混乱。由于子控制器是动态创建的,因此我不能简单地传递每个控制器所需的依赖关系。
我已经讨论过将依赖项存储在app存储库中并使用从中提取的信息调用子控制器,但这对我来说似乎仍然不对。在不使用服务定位器或其他反模式的情况下,这样做的正确方法是什么?
$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']);
}
}
答案 0 :(得分: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);
}
}
我希望建议一个容器(我正在开发PHP-DI),但这里有一个容器列表:https://gist.github.com/mnapoli/6159681