Doctrine 2 with Symfony DI Container

2019-02-19 23:56发布

I am working on a Zend Framework project that leverages Doctrine 2. I'm trying to get Symfony's DI container working with the project as well, but I'm having trouble. Suppose I have a class "Foo" that needs two instances injected. I can set up a Symfony DI container no problem to fetch me a new "Foo" with the dependencies injected. Great! But now what if I want to make "Foo" a Doctrine entity? All is well when I insert the entity to the DB because I can grab a new one from the DI container and simply persist the entity. However, when I query the entity from the DB Doctrine is instantiating my "Foo" instances and they will not have the proper dependencies injected. How do I get Doctrine to use my DI container so that the entity will have the appropriate dependencies? I know that Doctrine offers a "postLoad" hook in that I could use to inject dependencies on my entity, but that kind of defeats the purpose and benefit of the DI container.

2条回答
啃猪蹄的小仙女
2楼-- · 2019-02-20 00:40

A Doctrine Entity is a newable, not an injectable. Entities are not supposed to be created through a DIC. See this following blog post on the difference between newable and injectable:

http://misko.hevery.com/2008/09/30/to-new-or-not-to-new/

查看更多
戒情不戒烟
3楼-- · 2019-02-20 00:51

Its a bit tricky, but it can be done. There exists a patch for symfony di container which allows you to pass a already existing object to the container builder instance and let the di container configure it for you (e. g. inject dependencies based on interfaces). The patch is implemented in this repository on github: https://github.com/lstrojny/symfony but didn´t make it upstream to symfony master repository.

You use it like this:

$user = new User();
$container->configure('someId', $user);

Then you could register a PostLoad event handler with Doctrine´s EventManager (see here for more details: http://www.doctrine-project.org/docs/orm/2.0/en/reference/events.html ). In this event handler you configure the loaded entity via the aforementioned method. It´s obvious but you cant use constructor injection in this case, only setter.

This is a bit tricky to set up, but can be very powerful especially in conjunction with the ability of symfony di container to inject dependencies based on interfaces.

查看更多
登录 后发表回答