2016-04-21 47 views
-1

我的问题更多的是怀疑什么是最佳解决方案。注入提供者服务或容器。良好的做法

想象一下,我们需要实现一个处理程序,这取决于来自实体的一个参数。 让我解释一下

OPTION1

  • 服务/供应商/ HSBCProvider
  • 服务/供应商/ BarclaysProvider
  • 服务/ BankHandler
  • 控制器/ BankController

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); 
} 

OPTION 2

  • 服务/提供者/ HSBCProvider
  • 服务/提供者/ BarclaysProvider
  • 控制器/ BankController

BankController行动

public function createAction($id) { 
    $account = $repository->getAccount($id); 
    $bankProvider = $this->get('service.provider.'.account->getName()); 
    $bankProvider->do(); 
} 

使用此选项的BankHandler类不是不再需要

我简化所有的逻辑里面的创建和行动。

我不喜欢选项1因为我正在注射容器。 我不喜欢选项2 cos动作控制器有太多的逻辑(胖控制器?)。

还有其他更好的解决方案吗?

+0

在你的第一个选择,你的'BankHandler'类并不一定要依赖于容器。只需添加一个方法来向一个名称注册一个提供者,并在'create()'方法中返回这个提供者(或者也可以在那里应用您需要的任何逻辑)。 – xabbuh

+0

@xabbuh我不想在create方法中实例化提供程序类,因此我必须将其注入基于帐户名称的构造函数中。提供者服务已经正确注册 – Mauro

+1

这个问题-2有多糟? – Mauro

回答

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(); 
    } 
} 
+0

我喜欢你的想法。我唯一关心的是实例化大量注入注册表的提供程序。 – Mauro

+0

我不喜欢这样。无论用户是否使用,您都将实例化服务。注入容器并在需要时调用服务比这更好。 – LMS94

+0

@ LM94。那么你最喜欢的选择是1? – Mauro

相关问题