我的问题更多地是对良好实践方面最佳解决方案的疑问。
想象一下,我们需要根据来自实体的一个参数来实现处理程序。 让我解释一下
OPTION1
BankHandler
class BankHandler {
private $container;
function __contructor($container) {
$this->container = $container;
}
function create($account) {
$provider = $this->container->get('service.provider.'.$account->getName());
$provider->do();
}
}
BankController行动
public function createAction($id) {
$account = $repository->getAccount($id);
$bankHandler = $this->get('service.bank_handler');
$bankHandler->create($account);
}
选项2
BankController行动
public function createAction($id) {
$account = $repository->getAccount($id);
$bankProvider = $this->get('service.provider.'.account->getName());
$bankProvider->do();
}
使用此选项不再需要BankHandler类
我正在简化创建和动作中的所有逻辑。
我不喜欢选项1因为我正在注入容器。 我不喜欢Option 2 cos动作控制器有太多的逻辑(胖控制器?)。
还有其他更好的解决方案吗?
答案 0 :(得分:0)
为所有提供程序创建一个注册表服务,将其注入处理程序并从中获取提供程序。有些东西......
class BankProviderRegistry
{
/**
* @var array|BankProviderInterface[]
*/
private $providers = array();
public function __construct(array $providers = array())
{
foreach($providers as $name => $provider) {
$this->addProvider($name, $provider);
}
}
/**
* Add provider to registry
*
* @param string $name
* @param BankproviderInterface $provider
*/
public function addProvider($name, BankProviderInterface $provider)
{
$this->provider[$name] = $provider;
}
/**
* Get provider by name
*
* @param string $name
* @return BankproviderInterface
*/
public function getProvider($name)
{
if (!isset($this->providers[$name])) {
throw new \Exception(sprintf('Provider "%s" is not registered', $name));
}
return $this->providers[$name];
}
}
您可以在服务中添加这些内容,例如..
app.registry.bank_provider:
class: AppBundle\Registry\BankProviderRegistry
arguments:
-
'a name': '@app.provider.a_name'
'another name': '@app.provider.another_name'
..,在您的DI扩展中,在编译器传递中,或者可能在其他地方我没有想过。
然后你将它传递给你的处理程序并获得提供者...
class BankHandler
{
private $registry;
public function __contruct(BankProviderRegistry $registry) {
$this->registry = $registry;
}
public function create($account) {
$provider = $this->registry->getProvider($account->getName());
$provider->do();
}
}