Any chance someone is able to help me better understand this? It still 
isn't clear to me why addMethodCall fixes my circular dependency for a 
service definition but not when I add the method call via a compiler pass.

On Tuesday, August 28, 2012 5:52:26 PM UTC-7, Beau Simensen wrote:
>
> 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 [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/symfony-devs?hl=en

Reply via email to