我有类ModelsRepository:
class ModelsRepository extends EntityRepository
{}
Run Code Online (Sandbox Code Playgroud)
和服务
container_data:
class: ProjectName\MyBundle\Common\Container
arguments: [@service_container]
Run Code Online (Sandbox Code Playgroud)
我想从ModelsRepository访问service_data.我无法从控制器使用的构造函数传输服务.
你知道怎么做吗?
Tou*_*uki 13
恕我直言,这不应该是需要的,因为你可能很容易违反像SRP和Demeter法则这样的规则
但如果你真的需要它,这是一种方法:
首先,我们定义一个基础"ContainerAwareRepository"类,它有一个调用"setContainer"
services.yml
services:
# This is the base class for any repository which need to access container
acme_bundle.repository.container_aware:
class: AcmeBundle\Repository\ContainerAwareRepository
abstract: true
calls:
- [ setContainer, [ @service_container ] ]
Run Code Online (Sandbox Code Playgroud)
ContainerAwareRepository可能如下所示
AcmeBundle\Repository\ContainerAwareRepository.php
abstract class ContainerAwareRepository extends EntityRepository
{
protected $container;
public function setContainer(ContainerInterface $container)
{
$this->container = $container;
}
}
Run Code Online (Sandbox Code Playgroud)
然后,我们可以定义我们的模型库.
我们在这里使用了doctrine的getRepository方法来构建我们的存储库
services.yml
services:
acme_bundle.models.repository:
class: AcmeBundle\Repository\ModelsRepository
factory_service: doctrine.orm.entity_manager
factory_method: getRepository
arguments:
- "AcmeBundle:Models"
parent:
acme_bundle.repository.container_aware
Run Code Online (Sandbox Code Playgroud)
然后,只需定义类
AcmeBundle\Repository\ModelsRepository.php
class ModelsRepository extends ContainerAwareRepository
{
public function findFoo()
{
$this->container->get('fooservice');
}
}
Run Code Online (Sandbox Code Playgroud)
为了使用存储库,您绝对需要首先从服务中调用它.
$container->get('acme_bundle.models.repository')->findFoo(); // No errors
$em->getRepository('AcmeBundle:Models')->findFoo(); // No errors
Run Code Online (Sandbox Code Playgroud)
但如果你直接做
$em->getRepository('AcmeBundle:Models')->findFoo(); // Fatal error, container is undefined
Run Code Online (Sandbox Code Playgroud)
您永远不应该将容器传递给存储库,就像您永远不应该让实体处理繁重的逻辑一样.存储库只有一个目的 - 从数据库中检索数据.没有更多(阅读:http://docs.doctrine-project.org/en/2.0.x/reference/working-with-objects.html).
如果您需要比这更复杂的东西,您应该为此创建一个单独的(如果您愿意的容器).
我试过一些版本.问题解决了
ModelRepository:
class ModelRepository extends EntityRepository
{
private $container;
function __construct($container, $em) {
$class = new ClassMetadata('ProjectName\MyBundle\Entity\ModelEntity');
$this->container = $container;
parent::__construct($em, $class);
}
}
Run Code Online (Sandbox Code Playgroud)
security.yml:
providers:
default:
id: model_auth
Run Code Online (Sandbox Code Playgroud)
services.yml
model_auth:
class: ProjectName\MyBundle\Repository\ModelRepository
argument
Run Code Online (Sandbox Code Playgroud)
结果我得到了能力使用容器的存储库 - 根据需要.但是这种实现只能在关键情况下使用,因为她对Repository有限制.Thx 4all.