Skip to content

[DependencyInjection] inlined factory not referenced #12393

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from

Conversation

boekkooi
Copy link
Contributor

@boekkooi boekkooi commented Nov 3, 2014

Q A
Bug fix? yes
New feature? no
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets -
License MIT
Doc PR -

While working with the DI I encountered a You have requested a non-existent service "xxxxx" exception.
Research it seems that a private reference was inlined but the private factory that was also referencing to the service was ignored.

A example of the problem:

        <service id="manager"
                 class="\stdClass"
                 factory-method="getX"
                 factory-service="factory"
                 public="false">
            <argument>X</argument>
        </service>
        <service id="repository"
                 class="\stdClass"
                 factory-method="getRepository"
                 factory-service="manager"
                 public="false">
            <argument>X</argument>
        </service>
        <service id="storage" class="\stdClass" public="false">
            <argument type="service" id="manager"/>
            <argument type="service" id="repository"/>
        </service>

What happens before the patch:

  1. repository get's inlined
  2. manager get's inlined for the first argument
  3. manager get's removed since there was no reference.

After the first commit the following will happen:

  1. repository get's inlined
  2. manager get's inlined for the first argument
  3. manager will not be removed since the inlined repository still references manager

This introduced a smell since InlineServiceDefinitionsPass was still inlining the manager for the first argument.

To fix this I have chosen that not inline factories if they are used more then once by the same definition.

So after the second commit the following will happen:

  1. repository get's inlined

Personally I feel that the InlineServiceDefinitionsPass patch isn't the best possible one but that a different fix would probably mean breaking BC so it's probably a good idea to look at this for Symfony 3.0.

@boekkooi boekkooi force-pushed the di-factory-inline-patch branch from 8407681 to 806fbb7 Compare November 4, 2014 03:13
@boekkooi boekkooi changed the title Di factory inline patch [DependencyInjection] inlined factory not referenced Nov 4, 2014
@boekkooi boekkooi force-pushed the di-factory-inline-patch branch from 9c1cb9b to da6495b Compare November 7, 2014 01:47
@boekkooi
Copy link
Contributor Author

This bug is related to #11639 sorry for not catching this inlined problem back then.

@boekkooi
Copy link
Contributor Author

@fabpot Is there anything I can do to move this PR along?

@fabpot
Copy link
Member

fabpot commented Nov 12, 2014

Thank you @boekkooi.

fabpot added a commit that referenced this pull request Nov 12, 2014
…kooi)

This PR was submitted for the master branch but it was merged into the 2.3 branch instead (closes #12393).

Discussion
----------

[DependencyInjection] inlined factory not referenced

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | -
| License       | MIT
| Doc PR        | -

While working with the DI I encountered a `You have requested a non-existent service "xxxxx"` exception.
Research it seems that a private reference was inlined but the private factory that was also referencing to the service was ignored.

A example of the problem:
```XML
        <service id="manager"
                 class="\stdClass"
                 factory-method="getX"
                 factory-service="factory"
                 public="false">
            <argument>X</argument>
        </service>
        <service id="repository"
                 class="\stdClass"
                 factory-method="getRepository"
                 factory-service="manager"
                 public="false">
            <argument>X</argument>
        </service>
        <service id="storage" class="\stdClass" public="false">
            <argument type="service" id="manager"/>
            <argument type="service" id="repository"/>
        </service>
```

What happens before the patch:
1. repository get's inlined
2. manager get's inlined for the first argument
3. manager get's removed since there was no reference.

After the first commit the following will happen:
1. repository get's inlined
2. manager get's inlined for the first argument
3. manager will not be removed since the inlined repository still references manager

This introduced a smell since InlineServiceDefinitionsPass was still inlining the manager for the first argument.

To fix this I have chosen that not inline factories if they are used more then once by the same definition.

So after the second commit the following will happen:
1. repository get's inlined

Personally I feel that the InlineServiceDefinitionsPass patch isn't the best possible one but that a different fix would probably mean breaking BC so it's probably a good idea to look at this for Symfony 3.0.

Commits
-------

7816a98 [DependencyInjection] inlined factory not referenced
@fabpot fabpot closed this Nov 12, 2014
@boekkooi boekkooi deleted the di-factory-inline-patch branch November 12, 2014 09:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants