2016-11-14 75 views
2

似乎有两种方式在Symfony的动态实例化服务:Symfony - 使用服务工厂还是服务配置器更好?

这两种方法似乎是电流。检查问题和更改日志并没有给我更多的信息,哪些是最常见的或哪种方法被认为是最佳实践。

所以,我应该使用服务工厂在服务配置或服务配置了工厂?为什么和哪个更近?

非常感谢!

+0

其他几个人要求其公共接口的一部分的方法的参数,发布您的特定使用案例的详细信息。尤其要区分“编译时”配置和基于请求的“运行时”配置。 – Cerad

回答

0

使用服务工厂在服务配置是在一些特殊情况下,更好的决策:

1)创建服务定义为老年PHP类,因为在过去,创建逻辑往往隐藏静态工厂类 例如内,Doctrine_Core :: getTable()

public static function getTable($componentName) 
{ 
    return Doctrine_Manager::getInstance()->getConnectionForComponent($componentName)->getTable($componentName); 
} 

https://github.com/doctrine/doctrine1/blob/master/lib/Doctrine/Core.php

2)一个使用工厂服务和方法用于检索服务的特别好的例子是Doctrine存储库的 案例。当你需要一个,你通常会注入实体管理器作为 构造函数的参数,并在以后检索特定的资源库:

use Doctrine\ORM\EntityManager; 

class SomeClass 
{ 
    public function __construct(EntityManager $entityManager) 
    { 
     $this->entityManager = $entityManager; 
    } 

    public function doSomething() 
    { 
     $repository = $this->entityManager->getRepository('User'); 
    } 
} 

但是使用工厂服务和方法,你可以直接注入正确的库本身:

class SomeClass 
{ 
    public function __construct(UserRepository $userRepository) 
    { 
     $this->userRepository = $userRepository; 
    } 
} 

...

<service id="some_service" class="SomeClass"> 
    <argument type="user_repository" /> 
</service> 

...

<service id="user_repository" class="UserRepository" 
    factory-service="entity_manager" factory-method="getRepository"> 
    <argument>User</argument> 
</service> 

通过查看SomeClass的构造函数参数,立即清楚它需要一个 用户存储库,它比SomeClass需要EntityManager的早期示例更具体和更具通信性。除了使类本身更清洁,也会使 它更容易创建一个独立的对象存储库,当你正在编写单元测试这个 类。而不是创建两个实体管理器和库一个模拟的,你只需要 创建一个存储库本身。

缺点是(按Matthias ):

我反对静态工厂方法的工厂类是 静态代码是全局代码,并且该执行该代码可能有侧面 无法隔离的影响(例如在测试场景中)。 此外,这种静态工厂方法的任何依赖性必须由定义为静态的本身,这对隔离也是非常不利的,并且 可以防止您用自己的 代码替换(部分)创建逻辑。工厂对象(或工厂服务)略好。 然而,需要对他们非常有可能指向某种设计 问题。服务不应该需要工厂,因为它只会以预定的(确定的)方式创建 一次,并且从此 可以被任何其他对象完全重用。这是 动态有关服务的唯一的东西,应该是那个 是

+0

那么你真的可以在什么时候使用服务配置器?基本上,我的服务参数之一是在运行时动态定义的,info通过文件系统“发现”。 http://stackoverflow.com/questions/23156907/how-can-i-dynamically-set-a-parameter-in-symfony2 – Hussard

+0

你能更新与动态服务的代码原来的问题? –

2

基本上它们不一样:一个工厂用于创建服务,配置器用于创建后配置它。

当您需要实例化服务(也许注入其他服务或参数)时,请使用标准服务配置文件(即:services.yml)。

当您需要控制服务实例化时使用工厂。

当您需要在创建之后配置您的服务并且希望将服务定义与服务配置分开时使用服务配置器。

+0

您是否真的可以使用服务配置器?基本上,我的服务参数之一是在运行时动态定义的,info通过文件系统“发现”。 http://stackoverflow.com/questions/23156907/how-can-i-dynamically-set-a-parameter-in-symfony2 – Hussard

+0

@Hardard如果你阅读你链接的文档,你会发现真正的用例 – DonCallisto