繁体   English   中英

检测到服务的循环参考

[英]Circular reference detected for service

我有一个简单的 class 看起来像这样:

<?php
namespace App\Algorithm;

use App\Dao\MatchDao;
use App\Service\MatchService;

class Calculator {
    private $users;
    private $matchDao;

    function __construct(MatchService $matchService, MatchDao $matchDao) {
        $this->users = $matchService->users;
        $this->matchDao = $matchDao;
    }

    public function hourlyRate() {
        $query = $this->matchDao->getSingleColumn('Payment', 'hourly_rate', 32);
        var_dump($query);
    }
}

但我收到以下错误消息:

检测到服务“App\Algorithm\Calculator”的循环引用,路径:“App\Algorithm\Calculator -> App\Service\MatchService -> App\Algorithm\Calculator”。

MatchService.php

<?php
namespace App\Service;

use App\Algorithm\Calculator;
use App\Algorithm\Collection;

class MatchService {
    public $users;
    private $collection;
    private $calculator;

    function __construct(Collection $collection, Calculator $calculator) {
        $this->collection = $collection;
        $this->calculator = $calculator;
    }

    public function getMatch($data) {
        $this->users = $this->collection->getAllUsers($data);
        $this->calculator->hourlyRate();
        return 1;
    }

}

问题是MatchService但我到底做错了什么?

正如一些人指出的那样,循环依赖来自于您试图将 Calculator 注入 MatchService 并同时将 MatchService 注入 Calculator 的事实。 在创建另一个之前无法创建一个。

再深入一点,Calculator 似乎正在使用 MatchService 来获取用户列表。 作为第二个问题,计算器试图在 MatchService 生成用户之前获取用户。

这是一种可能的重构:

class Calculator
{
    private $matchDao;

    public function __construct(MatchDao $matchDao)
    {
        $this->matchDao = $matchDao;
    }
    public function getHourlyRate($users) // Added argument
    {
        $query = $this->matchDao->getSingleColumn('Payment', 'hourly_rate', 32);
    }
}
class MatchService
{
    private $collection;
    private $calculator;

    public function __construct(Collection $collection, Calculator $calculator)
    {
        $this->calculator = $calculator;
        $this->collection = $collection;
    }
    public function getMatch($data)
    {
        $users = $this->collection->getAllUsers($data);
        $this->calculator->getHourlyRate($users);
    }
}

从 Calculator 的构造函数中删除 MatchService 解决了循环依赖问题。 将 $users 传递给 getHourlyRate 解决了在用户可用之前尝试获取用户的问题。

这当然只是一种可能的解决方案。 从您发布的代码中不清楚 Calculator 是否真的需要 $users 。

很明显,您将服务 A 注入到服务 B 中,并将服务 B 注入到服务 A 中。这样做似乎不合逻辑,但有时是需要的。 就我而言,我有两项服务:

_MySession -> 原型 Symfony Session

_MyClient -> 负责识别客户端并获取其数据库凭据

我使用 MySession 来存储这些凭据,因此,它将可供整个系统使用,但是,要使用 MyClient 获取这些凭据,我需要将一些信息存储到 MySession 中......看,两个需要彼此的服务工作...

我开始看到同样的

检测到服务的循环参考

刚刚升级到 Symfony 5. 而且,sfy5 本身提出了解决方案:

composer require symfony/proxy-manager-bridge

请记住,服务可以设置为

lazy : true

有关Symfony 文档的更多信息

这通常发生在类相互依赖注入时,因此是循环引用。

给你上面的例子,你的 class MatchService注入CollectionCalculator 其中之一(假设计算器作为集合可能是 doctrine 类)依赖注入您的MatchService

这是我想象你的课程的方式:

class MatchService 
{
    public $users;
    private $collection;
    private $calculator;

    public function __construct(Collection $collection, Calculator $calculator) {
        $this->collection = $collection;
        $this->calculator = $calculator;
    }
}

class Calculator
{
    private $matchService;

    public function __construct(MatchService $matchService)
    {
        $this->matchService = $matchService;
    }
}

你有几个选择:

  • 更多服务,更少依赖
  • 使用静力学

我们很难为您解决问题,因为这取决于您如何构建应用程序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM