8000 Controlling the order of service decoration · Issue #10634 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

Controlling the order of service decoration #10634

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
stof opened this issue Apr 4, 2014 · 4 comments
Closed

Controlling the order of service decoration #10634

stof opened this issue Apr 4, 2014 · 4 comments

Comments

@stof
Copy link
Member
stof commented Apr 4, 2014

The new decorates feature of the component is great to allow composition. However, the order in which decorators are applied on a given service depends of the order in which definitions are found (the order in which services are defined probably, but not exactly in case service overwrites are involved).

services:
    foo:
        class: Foo

    bar:
        class: Bar
        arguments: ['@bar.inner']
        decorates: foo
        public: false

    foobar:
        class: Foobar
        arguments: ['@foobar.inner']
        decorates: foo
        public: false

This creates the following code (decorators are marked private so that everythng gets inlined so the code is real):

$this->services['foo'] = new Foobar(new Bar(new Foo)));

In some cases, the order of decorators does not really matters. However, there are cases where the order in which they are applied would be important. The current code does not allow to have the following result code:

$this->services['foo'] = new Bar(new Foobar(new Foo)));

Currently, we have some code in Behat 3.0 which is doing some decoration using tags to identify the services. The logic has some flaws (it copies the definition so a different service is used, but I plan to fix it), however it allows controlling the order in which decorators are applied thanks to a priority.
I think it would be great to support such priority for the decorates feature as well. This could be handled by passing a third argument to Definition::setDecoratedService (and using separate attributes in XML and YAML, with names to be determined). this would allow a future version of Behat to rely on the decorates feature rather than using a workaround (we cannot do it now as we want to keep the support of the 2.3 LTS)

@cordoval
Copy link
Contributor
cordoval commented Apr 4, 2014

👍 this should be then be labeled into the 2.5 or 3.0 milestone?

@stof
Copy link
Member Author
stof commented Apr 4, 2014

It does not need to wait 3.0. It is an enhancement to the feature merged in 2.5 a few days ago, and my enhancement proposal is BC. So even if we don't do it in 2.5, it can be done in 2.6 without waiting for 3.0

@fabpot
Copy link
Member
fabpot commented Apr 4, 2014

we need to do that in 2.5; the 2 months of stabilization is exactly when those kind of things must be done (even if it's not BC by the way).

@kipit
Copy link
Contributor
kipit commented Nov 29, 2014

Actually, the initialization depends on the order of services definitions.

So, to achieve:

$this->services['foo'] = new Bar(new Foobar(new Foo)));

we need to define bar after foobar.

While the code does not permit such initialization refinements, the config does.

@stof can you share code from Behat were you (try to?) achieve this?

@fabpot fabpot removed the Hackday label Feb 12, 2015
fabpot added a commit that referenced this issue Aug 5, 2015
…ty of service decoration (dosten)

This PR was merged into the 2.8 branch.

Discussion
----------

[DependencyInjection] Added a way to define the priority of service decoration

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #10634
| License       | MIT
| Doc PR        | symfony/symfony-docs#5600

This PR adds a way to define the priority of service decoration, so, the service with the highest priority will be applied first (the default priority is zero).

```yaml
services:
    foo:
        class: Foo

    bar:
        class: Bar
        arguments: ['@bar.inner']
        decorates: foo
        public: false

    foobar:
        class: Foobar
        arguments: ['@foobar.inner']
        decorates: foo
        decoration_priority: 1
        public: false
```

This will result in this code:

```php
$this->services['foo'] = new Bar(new Foobar(new Foo)));
```

Commits
-------

75c98cb Added a way to define the priority of service decoration
@fabpot fabpot closed this as completed Aug 5, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants
0