将EntityManager从另一个服务注入服务中

问题描述 投票:0回答:1

我正在从Controller中将代码提取到Symfony 3.4 App中的一种ApplicationService。

我有一个用于抓取数据的具体类,还有另一个用于更改某些数据的具体转换器。

src\App\Service 

class CompanyScraping implements ScrapingInterface
{
    private $crawler;

    public function __construct(CrawlerInterface $crawler)
    {
        $this->crawler = $crawler;

    }

    public function extract()
    {
        ...
    }

    public function transform()
    {
        $transformer = new concreteTransformer();

    }
}

class concreteTransformer
{
    private $em;

    public __construct(EntityManagerInterface $em)
    {
        $this->em = $em;
    }
}

如果未在CompanyScraping类中调用EntityManager,如何将EntityManager传递给concreteTransformer类?我无法使用新实例化ConcreteTransformer。

我在考虑这两个选项:

  • 将EntityManager传递给CompanyScraping,但我认为这是一个错误的主意,因为CompanyScraping不需要此依赖项。

  • 将转换方法提取到另一个类中,并从控制器/控制台传递em

$crawler =  new CompanyScraping(new GoutteClient());
$rawData = $crawler->extract(...);
$data = new concreteTransformer($em, $rawData);

还有其他想法吗?

谢谢。

php symfony private
1个回答
0
投票

我想到的第一个解决方案是将(不是EM,而是)将Transformer注入Scraper类,如评论中所述。

但是,这种解决方案无法解决潜在的问题:Scraper是抓取,转换还是两者同时进行?在后一种情况下,它不遵循单一责任原则,因为它既负责抓取转换,又负责。

一种可以非常有效地解决此问题的设计模式是decorator pattern。在这种情况下,其想法是通过转换“装饰”刮取的结果。

结果看起来像这样:

class Transformer implements ScrapingInterface
{
    private $scraper;
    private $em;

    public __construct(ScrapingInterface $scraper, EntityManagerInterface $em)
    {
        $this->scraper = $scraper;
        $this->em = $em;
    }

    public function extract()
    {
        return $this->transform($this->scraper->extract());
    }

    private function transform() {...}
}

它可以构造为:

$crawler = new Transformer(new CompanyScraping(new GoutteClient()), $em);

如果您有多个转换器实现,则可以使装饰器更加通用:

class TransformingScraper implements Scraper
{
    private $scraper;
    private $transformer;

    public __construct(Scraper $scraper, Transformer $transformer)
    {
        $this->scraper = $scraper;
        $this->transformer = $transformer;
    }

    public function extract()
    {
        return $this->transformer->transform($this->scraper->extract());
    }
}

$crawler = new TransformingScraper(
    new CompanyScraping(new GoutteClient()),
    new ConcreteTransformer($em)
);
© www.soinside.com 2019 - 2024. All rights reserved.