Service Container如何创建在services.yml中声明的对象?

时间:2012-02-04 20:52:00

标签: dependency-injection symfony

考虑以下代码:

public function showActiveJobsAction($slug)
{
     $em = $this->getDoctrine()->getEntityManager();
     $category = $em->getRepository('JobeetBundle:Category')->findBySlug($slug);
     if (! $category) {
        throw $this->createNotFoundException('Unable to find Category entity.');
     }

     $jobService = $this->container->get('job_service');
     $category = $jobService->populateCategoryByItsActiveJobs($category);

     return $this->render('JobeetBundle:Category:jobs.html.twig', array(
        'category'      => $category,
    ));        
}

job_service需要JobeetBundle:类别存储库才能工作。存储库将传递给服务构造函数。它全部在services.yml

中定义

所以在这种情况下,我最终得到了两个JobeetBundle实例:Category repository class?

如果是,我怎样才能改变设计以做得更好?

创建代码可能更好:

$jobService->getCatetoryWithActiveJobsByItsSlug($slug)

但是我仍然想知道容器在创建它之前是否存在物体存在?

2 个答案:

答案 0 :(得分:2)

当您从容器中获取服务时,默认情况下,您始终获得相同的实例。将此服务注入另一个服务时,它也是同一个实例。

所以你没有两个担心,你只得到一个服务实例job_service

以下是Symfony2 book, chapter Service Container的摘录:

  

作为额外的奖励,Mailer服务仅创建一次,每次请求服务时都会返回相同的实例。这几乎总是你需要的行为(它更灵活,更强大)。

希望有所帮助!

答案 1 :(得分:1)

一般情况下,您不会在Symfony2中获得重复的存储库(或服务),因此不必担心。

此:

$jobService->getCatetoryWithActiveJobsByItsSlug($slug)

这是一种更好的方法,因为它隐藏了控制器中的实体管理器/存储库内容。你可以(理论上至少)将整个Doctrine2引擎换成其他东西,并且仍然可以使用你的控制器代码。