8000 [DI] Rework config hierarchy: defaults > instanceof > service config by nicolas-grekas · Pull Request #22356 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[DI] Rework config hierarchy: defaults > instanceof > service config #22356

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

Merged
merged 3 commits into from
Apr 11, 2017

Conversation

nicolas-grekas
Copy link
Member
@nicolas-grekas nicolas-grekas commented Apr 10, 2017
Q A
Branch? 3.3
Bug fix? yes
New feature? no
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets -
License MIT
Doc PR -

Replaces #22294.
The main change is that ChildDefinition does not have "instanceof" applied anymore. All the complexity of the pass came from the merging logic required to deal with them. But in fact, we'd better not have any such logic and just not apply "instanceof" to ChildDefinition (but have them inherit from their parents with the usual logic).

*/
public function setChanges(array $changes)
{
$this->changes = array();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$this->changes = $changes?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch, fixed

}
}
if ($didProcess) {
$container->register('abstract.'.__CLASS__, '')->setAbstract(true);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the goal of this ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's the base abstract service all "instanceof" chains inherit from. See L56 below.

'abstract' => 'abstract',
'deprecated' => 'deprecated',
'factory' => 'factory',
'arguments' => 'arguments',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you removing these ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because they make no sense as "instanceof" conditionals.
(borrowed from #22294, ping @weaverryan for more info)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly, I thought these were an "abuse" of instanceof - these things are better handled with a normal parent-child. But, I suppose there's nothing wrong with having them.

However, I think arguments should not be included. A definition could have multiple instanceof. And with parent-child, the child opts into its 1 specific parent. But with instanceof, these can be applied without the child knowing. I feel like there will be merging edge-cases with arguments.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's discuss more the use of factory inside defaults and/or instanceof sections in #22189.

/**
* Sets the tracked changes for the Definition object.
*
* @return $this
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe @internal?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not need imho

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would mark both getChanges() and setChanges() as @internal.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ChilDefinition::getChanges can't be made internal ("bc break")

}
$value->setInheritTags(false);

if (!$this->container->has($parent = $value->getParent())) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This surprised me at first - it looks like we're silencing invalid parent ids. But, you've done this simply so that the later ResolveDefinitionTemplatesPass can throw the proper exception. Maybe add a one-line comment mentioning a later pass checks for parent validity? I want to leave some breadcrumbs for the future :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually, I made it throw, so that tag inheritance is made incompatible with dynamically created parents and save a few surprises (since tags would not be inherited for them, despite the field)

{
$didProcess = false;
foreach ($container->getDefinitions() as $id => $definition) {
if ($definition instanceof ChildDefinition) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could add a one-line comment here:

Don't apply instanceof to children definition (but it will still be applied to their parent)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment added


if (isset($instanceofParent->getChanges()['shared'])) {
$shared = $instanceofParent->isShared();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does shared need to be treated special? It looks like ResolveDefinitionTemplatesPass now treats it like any other field, so wouldn't that take care of this without any special code?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shared is not handled as the other fields (that'd be a BC break): it is never inherited from the parent, as before (see lines after "purposely ignored attributes": there is no "setShared" call there)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right - and the integration test proves this. I didn't see it at first :)

@weaverryan
Copy link
Member

👍

I've tested this, it's clear and I like it!

@fabpot
Copy link
Member
fabpot commented Apr 11, 2017

Thank you @nicolas-grekas.

@fabpot fabpot merged commit 6d6116b into symfony:master Apr 11, 2017
fabpot added a commit that referenced this pull request Apr 11, 2017
…service config (weaverryan, nicolas-grekas)

This PR was merged into the 3.3-dev branch.

Discussion
----------

[DI] Rework config hierarchy: defaults > instanceof > service config

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

Replaces #22294.
The main change is that ChildDefinition does not have "instanceof" applied anymore. All the complexity of the pass came from the merging logic required to deal with them. But in fact, we'd better not have any such logic and just not apply "instanceof" to ChildDefinition (but have them inherit from their parents with the usual logic).

Commits
-------

6d6116b Adding an integration test for the hirarchy of defaults, instanceof, child, parent definitions
ab86457 [DI] Rework config hierarchy: defaults > instanceof > service config
cbaee55 [DI] Track changes at the "Definition" level
@nicolas-grekas nicolas-grekas deleted the di-instanceof-order branch April 11, 2017 16:41
@nicolas-grekas
Copy link
Member Author

and thank you @weaverryan :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants
0