Symfony 5 中奇怪的循环依赖
Strange circular dependency in Symfony 5
我遇到 Symfony 5 及其循环依赖检测机制的问题。
我定义了以下内容class
namespace App\HTSC\Entity\Finance\Subscription;
/**
* Category
*/
class Category {
/**
* @var string
*/
private $name;
/**
* @var integer
*/
private $version = 1;
/**
* @var integer
*/
private $id;
/**
* @var array
*/
private $fees;
/**
* Map of feeType => fee
* @var array
*/
private $feeMap = null;
/**
* Constructor
*/
public function __construct(Category $category = null)
{
if (!is_null($category)) {
$this->name = $category->name;
$this->setFees($category->fees);
} else {
$this->fees = array();
}
}
/**
* Set name
*
* @param string $name
* @return Category
* @throws \InvalidArgumentException
*/
public function setName($name)
{
if (is_null($name) || empty($name = trim($name))) {
return \InvalidArgumentException('Empty category name');
}
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set version
*
* @param integer $version
* @return Category
*/
public function setVersion($version)
{
$this->version = $version;
return $this;
}
/**
* Get version
*
* @return integer
*/
public function getVersion()
{
return $this->version;
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Sets an array of fees to the category.
*
* @param array $fees
* @return Category
*/
public function setFees(array $fees) {
$this->fees = array();
$this->feeMap = array();
foreach ($fees as $fee) {
$this->addFee($fee);
}
return $this;
}
/**
* Add fee to category. Only one fee per fee type allowed.
*
* @param Fee $fee
* @return Category
*/
public function addFee(Fee $fee)
{
if (!$fee->isValid()) throw new \InvalidArgumentException('Invalid fee added to category');
$feeMap = $this->getFeeMap();
if (key_exists($fee->getType()->getName(), $feeMap)) {
throw new \InvalidArgumentException('Multiple fee type [' . $fee->getType()->getName() . '] specified for category [' . $this->name . ']');
}
$this->fees[] = $fee;
$this->feeMap[$fee->getType()->getName()] = $fee;
return $this;
}
/**
* Remove fee
*
* @param Fee $fee
* @return Category
*/
public function removeFee(Fee $fee)
{
$this->fees->removeElement($fee);
return $this;
}
/**
* Get fees
*
* @return Fee[]
*/
public function getFees()
{
return $this->fees;
}
/**
* Get fee of given type. Returns null if type is not present.
*
* @return Fee
*/
public function getFee(FeeType $type)
{
$feeMap = $this->getFeeMap();
if (key_exists($type->getName(), $feeMap)) return $feeMap[$type->getName()];
return null;
}
private function getFeeMap() {
if (is_null($this->feeMap)) {
$this->feeMap = array();
foreach ($this->fees as $fee) $this->feeMap[$fee->getType()->getName()] = $fee;
}
return $this->feeMap;
}
/**
* Returns whether a category is considered valid.
* @return boolean
*/
public function isValid() {
if (empty($this->name)) return false;
if (empty($this->fees)) return false;
return true;
}
}
当我访问该网站并因此访问我上面的代码时,Symfony 响应以下消息:
Circular reference detected for service "App\HTSC\Entity\Finance\Subscription\Category", path: "App\HTSC\Entity\Finance\Subscription\Category -> App\HTSC\Entity\Finance\Subscription\Category".
通常当检测到循环依赖时,会涉及第二个class;在我的例子中,它是 class 本身之间的循环依赖?
我还使用此 class 检查了其他 classes,但无法确定任何地方与此 class 的循环依赖关系。
有人遇到过同样的问题并且知道解决方案吗?
如果这是一个模型或实体,它应该不注册为服务。
因为它被注册为服务,所以它试图在构造函数中将 Category
服务设置为 Category
:
public function __construct(Category $category = null)
如果您已在 services.yaml
中明确将此注册为服务,请取消注册。
如果您没有明确注册它,请在您的自动布线中排除它。例如,如果您有一个条目:
App\:
resource: '../src/*'
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
然后确保将保存您的 class 的文件夹添加到 exclude
值。
请注意,此处也排除了“普通”(根级别)Entities
。
我遇到 Symfony 5 及其循环依赖检测机制的问题。
我定义了以下内容class
namespace App\HTSC\Entity\Finance\Subscription;
/**
* Category
*/
class Category {
/**
* @var string
*/
private $name;
/**
* @var integer
*/
private $version = 1;
/**
* @var integer
*/
private $id;
/**
* @var array
*/
private $fees;
/**
* Map of feeType => fee
* @var array
*/
private $feeMap = null;
/**
* Constructor
*/
public function __construct(Category $category = null)
{
if (!is_null($category)) {
$this->name = $category->name;
$this->setFees($category->fees);
} else {
$this->fees = array();
}
}
/**
* Set name
*
* @param string $name
* @return Category
* @throws \InvalidArgumentException
*/
public function setName($name)
{
if (is_null($name) || empty($name = trim($name))) {
return \InvalidArgumentException('Empty category name');
}
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set version
*
* @param integer $version
* @return Category
*/
public function setVersion($version)
{
$this->version = $version;
return $this;
}
/**
* Get version
*
* @return integer
*/
public function getVersion()
{
return $this->version;
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Sets an array of fees to the category.
*
* @param array $fees
* @return Category
*/
public function setFees(array $fees) {
$this->fees = array();
$this->feeMap = array();
foreach ($fees as $fee) {
$this->addFee($fee);
}
return $this;
}
/**
* Add fee to category. Only one fee per fee type allowed.
*
* @param Fee $fee
* @return Category
*/
public function addFee(Fee $fee)
{
if (!$fee->isValid()) throw new \InvalidArgumentException('Invalid fee added to category');
$feeMap = $this->getFeeMap();
if (key_exists($fee->getType()->getName(), $feeMap)) {
throw new \InvalidArgumentException('Multiple fee type [' . $fee->getType()->getName() . '] specified for category [' . $this->name . ']');
}
$this->fees[] = $fee;
$this->feeMap[$fee->getType()->getName()] = $fee;
return $this;
}
/**
* Remove fee
*
* @param Fee $fee
* @return Category
*/
public function removeFee(Fee $fee)
{
$this->fees->removeElement($fee);
return $this;
}
/**
* Get fees
*
* @return Fee[]
*/
public function getFees()
{
return $this->fees;
}
/**
* Get fee of given type. Returns null if type is not present.
*
* @return Fee
*/
public function getFee(FeeType $type)
{
$feeMap = $this->getFeeMap();
if (key_exists($type->getName(), $feeMap)) return $feeMap[$type->getName()];
return null;
}
private function getFeeMap() {
if (is_null($this->feeMap)) {
$this->feeMap = array();
foreach ($this->fees as $fee) $this->feeMap[$fee->getType()->getName()] = $fee;
}
return $this->feeMap;
}
/**
* Returns whether a category is considered valid.
* @return boolean
*/
public function isValid() {
if (empty($this->name)) return false;
if (empty($this->fees)) return false;
return true;
}
}
当我访问该网站并因此访问我上面的代码时,Symfony 响应以下消息:
Circular reference detected for service "App\HTSC\Entity\Finance\Subscription\Category", path: "App\HTSC\Entity\Finance\Subscription\Category -> App\HTSC\Entity\Finance\Subscription\Category".
通常当检测到循环依赖时,会涉及第二个class;在我的例子中,它是 class 本身之间的循环依赖?
我还使用此 class 检查了其他 classes,但无法确定任何地方与此 class 的循环依赖关系。
有人遇到过同样的问题并且知道解决方案吗?
如果这是一个模型或实体,它应该不注册为服务。
因为它被注册为服务,所以它试图在构造函数中将 Category
服务设置为 Category
:
public function __construct(Category $category = null)
如果您已在 services.yaml
中明确将此注册为服务,请取消注册。
如果您没有明确注册它,请在您的自动布线中排除它。例如,如果您有一个条目:
App\:
resource: '../src/*'
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
然后确保将保存您的 class 的文件夹添加到 exclude
值。
请注意,此处也排除了“普通”(根级别)Entities
。