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

Reply via email to