I'm using a Compiler Pass to add an `addMethodCall` to a service definition to register tagged services. However, it seems that my `addMethodCall` is being added to the container definition in such a way that it is causing a circular reference. Here is my desired container configuration:
<service id="data_provider_manager" /> <service id="formatter_manager"> <argument type="service" id="data_provider_manager" /> </service> <service id="some_special_data_provider"> <argument type="service" id="formatter_manager" /> <tag name="data_provider" alias="some_special" /> </service> My expectation is for the following to happen: $dataProviderManager = new DataProviderManager; $formatterManager = new FormatterManager($dataProviderManager); $someSpecialDataProvider = new SomeSpecialDataProvider($formatterManager); // ... at some point later. $dataProviderManager->registerDataProvider('some_special', $someSpecialDataProvider); This is not what happens. :) It looks like the registerDataProvider() method is called right after $dataProviderManager is instantiated. Which has a dependency on $someSpecialDataProvider, which depends on $formatterManager, which depends on $dataProviderManager. So I can see that there is a circular reference *if the registerDataProvider happens as soon as $dataProviderManager is requested*. I have temporarily solved this problem by doing the following configuration instead: <service id="data_provider_manager" /> <service id="formatter_manager"> <call method="setDataProviderManager"> <argument type="service" id="data_provider_manager" /> </call> </service> <service id="some_special_data_provider"> <argument type="service" id="formatter_manager" /> <tag name="data_provider" alias="some_special" /> </service> I'm not entirely certain why this works when my original service configuration did not. It seems to me as though they are both calling methods (`registerDataProvider` and `setDataProviderManager`) but this somehow breaks the circular reference. I have two question: 1) Can someone unwind for me what is going on here and why making this change removes the circular dependency from my configuration? 2) My naive understanding was that the `setDataProviderManager` call, as configured from the service configuration, must be being added to the container at a different part of the container compilation lifecycle. If this is the case, is there any way for me to have my data_provider tag do the same thing? If so, will I be able to get away from the circular reference problem without having to use `setDataProviderManager`? From looking at the container cache I can't see that this is actually the case, though. I'm guessing if there is a solution to this it will involve using a non-default PassConfig. I tried the PassConfig used by the kernel listener but it made no difference. The docs were not very clear on when you would use a certain PassConfig so I'm not sure if any of them would actually be useful. I asked on the Symfony Users group and didn't get very far. I had a few people question the design of the classes. That is a fair point, and I very well may try to find a way for formatter_manager to not depend on data_provider_manager, but I would like to not get bogged down in those details. I'm mainly hoping to find out more about the container lifecycle and whether or not there is something I can do with my Compiler Pass to add the method call to another part of the lifecycle so that my data provider can be registered in such a way that I don't have to worry about calling `setDataProviderManager` on my Formatter Manager. -- If you want to report a vulnerability issue on symfony, please send it to security at symfony-project.com You received this message because you are subscribed to the Google Groups "symfony developers" group. To post to this group, send email to symfony-devs@googlegroups.com To unsubscribe from this group, send email to symfony-devs+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/symfony-devs?hl=en