尝试升级现有的Symfony 3.3.2项目以使用自动装配 按照此处的说明操作:https://symfony.com/doc/current/service_container/3.3-di-changes.html#content_wrapper。
对我来说不起作用的是能够将目录中的所有服务设置为公共。
重要提示:我的services.yml文件位于src / SiteBundle / Resources / config中,而不是app / config。
# src/SiteBundle/Resources/config/services.yml
services:
_defaults:
autowire: true
autoconfigure: true
public: false
SiteBundle\Service:
resource: '../../Service'
public: true
CustomerOrderMasterRepository:
class: Doctrine\ORM\EntityRepository
factory: ["@doctrine.orm.entity_manager", get_repository]
arguments:
- SiteBundle\Entity\CustomerMaster
SiteBundle\Service\CustomersService:
arguments:
- '@doctrine.orm.entity_manager'
- '@CustomerMasterRepository'
如果我然后进行控制台调试:container | grep -i服务,它只显示输出头和Symfony服务容器。没有选择src / SiteBundle / Service目录中的类。
Symfony Container公共服务服务ID
班级名称service_container
的Symfony \组件\ DependencyInjection \ ContainerInterface
如果我添加--show-private,则显示它们(以及许多其他内容)。
Symfony Container公共和私人服务服务ID
班级名称
1_bcf140bb848ef41617942628c8525b4872574e826d00fee6aaabbf2ede89fbb8
Symfony的\分量\ DependencyInjection \服务定位
PSR \集装箱\ ContainerInterface
" service_container"的别名 SiteBundle \服务\ CustomerOrdersService
SiteBundle \服务\ CustomerOrdersService
SiteBundle \服务\ CustomersService
SiteBundle \服务\ CustomersService
SiteBundle \服务\ InventoryItemsService
SiteBundle \服务\ InventoryItemsService
SiteBundle \服务\ VendorOrdersService
SiteBundle \服务\ VendorOrdersService
SiteBundle \服务\ VendorsService
SiteBundle \服务\ VendorsService
SiteBundle \服务\ WorkOrdersService
SiteBundle \服务\ WorkOrdersService
Symfony的\分量\ DependencyInjection \ ContainerInterface
" service_container"的别名argument_resolver.service
Symfony的\分量\ HttpKernel \控制器\ ArgumentResolver \ ServiceValueResolver routing.loader.service
Symfony的\分量\路由\装载机\ DependencyInjection \ ServiceRouterLoader security.authentication.rememberme.services.abstract
security.authentication.rememberme.services.persistent
Symfony的\分量\安全\ HTTP \与rememberMe \对PersistentTokenBasedRememberMeServices security.authentication.rememberme.services.simplehash
Symfony的\分量\安全\ HTTP \与rememberMe \ TokenBasedRememberMeServices service_container
Symfony的\分量\ DependencyInjection \ ContainerInterface
service_locator.1712c3a50d1ec2c742b2ead0f03bb76c
Symfony的\分量\ DependencyInjection \服务定位
service_locator.26ac001b3ede28481ac0de703666b4d7
Symfony的\分量\ DependencyInjection \服务定位
service_locator.39e66930232432ca5ba91e98fdd8a17b
Symfony的\分量\ DependencyInjection \服务定位
service_locator.6f24348b77840ec12a20c22a3f985cf7
Symfony的\分量\ DependencyInjection \服务定位
service_locator.8925f20c49cbd61fcb37adf8c595459e
Symfony的\分量\ DependencyInjection \服务定位
service_locator.b8d2046fb854cde05549fb309e1a80d2
别名 " 1_bcf140bb848ef41617942628c8525b4872574e826d00fee6aaabbf2ede89fbb8"
service_locator.ceb8bbb9f48e8bfd1c8ec2d209eabdca
的Symfony \组件\ DependencyInjection \服务定位
如果我注释掉SiteBundle \ Service \ CustomerService定义,则debug:container命令会抛出此异常:
PHP致命错误:未捕获 Symfony的\分量\ DependencyInjection \异常\ AutowiringFailedException: 无法自动服务" SiteBundle \ Entity \ CustomerMasterRepository": 争论" $ em"方法 "学说\ ORM \ EntityRepository :: __构建体()"必须有一个类型提示 或明确给出一个值。 坦率地说,我不能做出头脑或尾巴。
连连呢? 感谢。
答案 0 :(得分:1)
这是主要问题:
PHP致命错误:未捕获的Symfony \ Component \ DependencyInjection \ Exception \ AutowiringFailedException:无法自动装配服务“SiteBundle \ Entity \ CustomerMasterRepository”:方法“Doctrine \ ORM \ EntityRepository :: __ construct()”的参数“$ em”必须具有类型提示或明确赋予值。坦率地说,我无法做出头脑或尾巴。
当您使用EntityRepository作为服务时,会发生这种情况,但是继承自Doctrine BaseRepository。这种组合永远不会发生。
存储库应该使用组合来获取Doctrine 像这样:
<?php
namespace AppBundle\EntityRepository;
use AppBundle\Entity\Channel;
use Doctrine\ORM\EntityManager;
class ChannelRepository
{
private $repository;
public function __construct(EntityManager $entityManager)
{
$this->repository = entityManager->getRepository(Channel::class);
}
public function getOneByName(string $name)
{
return $this->repository->findOneBy(['name' => $name]);
}
}
如果您想了解更多信息,可以发布包含精彩代码示例的帖子:How to use Repository with Doctrine as Service in Symfony
答案 1 :(得分:0)
要使自定义存储库正常工作,我必须覆盖__construct
方法以提供EntityManager
和ClassMetadata
,如下所示:
应用程序/配置/ services.yml
services:
_defaults:
autowire: true
autoconfigure: true
public: false
app.repository.channel:
class: \AppBundle\EntityRepository\ChannelRepository
的src /的appbundle / EntityRepository / ChannelRepository.php:
<?php
namespace AppBundle\EntityRepository;
use AppBundle\Entity\Channel;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Mapping\ClassMetadata;
class ChannelRepository extends RepositoryFactory
{
public function __construct(EntityManager $entityManager)
{
parent::__construct($entityManager, new ClassMetadata(Channel::class));
}
public function getOneByName(string $name)
{
return $this->findOneBy(['name' => $name]);
}
}
的src /的appbundle /实体/ Channel.php
<?php
namespace AppBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table(name="channel")
* @ORM\Entity(repositoryClass="\AppBundle\EntityRepository\ChannelRepository")
*
*/
class Channel
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @return int
*/
public function getId()
{
return $this->id;
}
}