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