如何将实体自动装配到服务中?
How to autowire an entity into a service?
我有一个名为 AbstractMediaService
的抽象 class 和这个抽象的一些特定实现 class:
abstract class AbstractMediaService
{
private $em;
private $media;
public function __construct(EntityManagerInterface $em, Media $media)
{
$this->em = $em;
$this->media = $media;
}
public function dosomethingInCommon();
abstract public function dosomethingSpecific();
}
class PhotoMediaService extends AbstractMediaService
{
public function dosomethingSpecific()
{
echo 'i am a photo service';
}
}
class VideoMediaService extends AbstractMedia
{
public function dosomethingSpecific()
{
echo 'i am a video service';
}
}
这些对象需要 Media
实体才能使用
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
class Media
{}
控制器
/**
* @Route("/{_locale}/infos/{idMedia}.html", name="info", methods={"GET"}, requirements={
* "idMedia" = "\d+",
* })
*/
public function infosPhotoAction(RequestStack $requestStack, Media $media)
{
$request = $requestStack->getCurrentRequest();
$session = $requestStack->getSession();
$media = new PhotoMedia($media);
// return response
}
问题是我需要一些依赖项,例如 Security
服务或 EntityManager
。
我想知道如何自动装配 AbstractMediaService
服务。
这是错误的。您不能自动装配 Media
以注入到服务中,因为 实体不是服务 。
public function __construct(EntityManagerInterface $em, Media $media)
如果 VideoMediaService
和 PhotoMediaService
(为了清楚起见,我重命名了它们,因为与您的实体共享名称使其看起来像是相关的)需要 Media
的实例来执行一些工作,只需将其作为相应方法的参数即可。
public function dosomethingInCommon(Media $media);
abstract public function dosomethingSpecific(Media $media);
或者,只需在 class 上使用 setMedia(Media $media)
方法即可:
public function setMedia(Media $media) {
$this->media = $media;
}
坦率地说,后一种方法似乎不是一个好主意。您需要让在 $media
上工作的方法意识到 setMedia()
尚未被调用的可能性,否则对 setMedia()
的后续调用将改变服务的行为方式。将其作为适当方法的参数会更干净、更清晰、更安全。
注入这些服务的方式与其他任何服务一样。他们扩展抽象 class 是无关紧要的。
/**
* @Route("/{_locale}/infos/{idMedia}.html", name="info", methods= {"GET"}, requirements={
* "idMedia" = "\d+",
* })
*/
public function infosPhotoAction(RequestStack $requestStack, Media $media, PhotoMediaService $photoMediaService): Response
{
$request = $requestStack->getCurrentRequest();
$session = $requestStack->getSession();
$photoMediaService->doSomethingSpecific($media)
return new Response('all done');
}
我有一个名为 AbstractMediaService
的抽象 class 和这个抽象的一些特定实现 class:
abstract class AbstractMediaService
{
private $em;
private $media;
public function __construct(EntityManagerInterface $em, Media $media)
{
$this->em = $em;
$this->media = $media;
}
public function dosomethingInCommon();
abstract public function dosomethingSpecific();
}
class PhotoMediaService extends AbstractMediaService
{
public function dosomethingSpecific()
{
echo 'i am a photo service';
}
}
class VideoMediaService extends AbstractMedia
{
public function dosomethingSpecific()
{
echo 'i am a video service';
}
}
这些对象需要 Media
实体才能使用
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
class Media
{}
控制器
/**
* @Route("/{_locale}/infos/{idMedia}.html", name="info", methods={"GET"}, requirements={
* "idMedia" = "\d+",
* })
*/
public function infosPhotoAction(RequestStack $requestStack, Media $media)
{
$request = $requestStack->getCurrentRequest();
$session = $requestStack->getSession();
$media = new PhotoMedia($media);
// return response
}
问题是我需要一些依赖项,例如 Security
服务或 EntityManager
。
我想知道如何自动装配 AbstractMediaService
服务。
这是错误的。您不能自动装配 Media
以注入到服务中,因为 实体不是服务 。
public function __construct(EntityManagerInterface $em, Media $media)
如果 VideoMediaService
和 PhotoMediaService
(为了清楚起见,我重命名了它们,因为与您的实体共享名称使其看起来像是相关的)需要 Media
的实例来执行一些工作,只需将其作为相应方法的参数即可。
public function dosomethingInCommon(Media $media);
abstract public function dosomethingSpecific(Media $media);
或者,只需在 class 上使用 setMedia(Media $media)
方法即可:
public function setMedia(Media $media) {
$this->media = $media;
}
坦率地说,后一种方法似乎不是一个好主意。您需要让在 $media
上工作的方法意识到 setMedia()
尚未被调用的可能性,否则对 setMedia()
的后续调用将改变服务的行为方式。将其作为适当方法的参数会更干净、更清晰、更安全。
注入这些服务的方式与其他任何服务一样。他们扩展抽象 class 是无关紧要的。
/**
* @Route("/{_locale}/infos/{idMedia}.html", name="info", methods= {"GET"}, requirements={
* "idMedia" = "\d+",
* })
*/
public function infosPhotoAction(RequestStack $requestStack, Media $media, PhotoMediaService $photoMediaService): Response
{
$request = $requestStack->getCurrentRequest();
$session = $requestStack->getSession();
$photoMediaService->doSomethingSpecific($media)
return new Response('all done');
}