Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork9.7k
[DI] Add "inherit-tags" with configurable defaults + same for "public", "tags" & "autowire"#21071
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
ogizanagi commentedDec 27, 2016 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Looks like a good idea to me. What about aliases, though? service_defaults:public:['aliases']# aliases are public whereas services are privateservice_defaults:public:true# default: aliases and services are public <=> ['aliases', 'services']service_defaults:public:false# aliases and services are private <=> [] (It'll need a special treatment for the |
linaori commentedDec 27, 2016
What about adding tags like this? I often find myself with a specific service definition file that contains a specific type of services. Think of a file for form types, they all have the same tag. It would be really nice if I could use this feature to automatically tag all definitions in that file by this implicit parent definition. |
GuilhemN commentedDec 27, 2016
👍, you should add this new sectionhere or the ContainerBuilder will throw an exception. |
ac66912 tocd74550Comparejaviereguiluz commentedDec 27, 2016
Minor comment: could we please take some time to think about this proposal before merging it? This kind of changes can have a deep impact in how developers use Symfony. Personally I don't have an opinion about the idea yet ... but I don't like the implementation. It doesn't feel "natural" for Symfony. |
ogizanagi commentedDec 27, 2016 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
As soon as it doesn't behaves blindly as a pseudo parent definition, but rather as a context/configuration exploitable by the loaders, it looks good to me. Hence, I don't really like the |
| if (!is_array($content['services'])) { | ||
| thrownewInvalidArgumentException(sprintf('The "services" key should contain an array in %s. Check your YAML syntax.',$file)); | ||
| } | ||
| $defaults =isset($content['service_defaults']) ?$content['service_defaults'] :array(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I think unsupported keys should throw an exception to be consistent with the rest of the loader.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
done
nicolas-grekas commentedDec 27, 2016 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
@javiereguiluz don't worry we have a process for that, this PR is no exception. @ogizanagi I'm 👎 on |
nicolas-grekas commentedDec 27, 2016 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
PR completed for YamlLoader. If someone would like to work on XmlLoader, I'd happily accept a PR againstmy branch! |
ro0NL left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
👍
| if (isset($service['alias'])) { | ||
| $public =!array_key_exists('public',$service)|| (bool)$service['public']; | ||
| $public =array_key_exists('public',$service)? (bool)$service['public'] : !empty($defaults['public']); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Any reason to define this variable twice? One doingarray_key_exists otherisset?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
these are not on the same path, and don't have the same semantic (don't forget about ChildDefinition on the other path.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I had services defined: (Symfony 3.1.8):
foo:class:My\FooServicebar:alias:foo
I could accessbar service in my controller because it was public by default. After this change here my aliased service is private by default, thus the service is not accessible in controller.
Shouldn't this be mentioned somewhere? I couldn't find any info about it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Good catch. That's a bug. See#21219
| thrownewInvalidArgumentException(sprintf('Service defaults must be an array, "%s" given in "%s".',gettype($defaults),$file)); | ||
| } | ||
| foreach ($defaultsas$key =>$default) { | ||
| if (!in_array($key,$defaultKeys)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Perhaps go strict here?
nicolas-grekasDec 27, 2016 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
done this way for consistency with the many otherin_array in this file, good enough anyway
dunglas commentedDec 28, 2016 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
I like the idea! What about using just defaults:public:falseautowire:['_construct', 'set*']services:foo:class:Foo The best looking config is: services:defaults:public:falseautowire:['_construct', 'set*']'Foo\Bar':{} But I'm not sure that it's ok to deprecate some services names like |
ro0NL commentedDec 28, 2016 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Really? The one above looks more intuitive to me... defaults:#...services:#... that is. Looking at it like this looks good... then again; if parameters are involved ( Meaning either |
nicolas-grekas commentedDec 28, 2016 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
The root namespace is used for container extensions configuration, that means there is a potential for collision with an existing bundle that uses this "defaults" name. framework:#...services:#...defaults:#... it's not intuitive at all that |
nicolas-grekas commentedDec 28, 2016
What about adding an underscore in this way? services:_defaults:#... |
ro0NL commentedDec 28, 2016
Perhaps |
nicolas-grekas commentedDec 28, 2016
I doubt |
ro0NL commentedDec 28, 2016
Think you're right.. just typed it out to visualize in fact. It looks good (imo.) but indeed..you need to know it.
|
GuilhemN commentedDec 28, 2016
What about using something that sounds more specific to yaml such as |
nicolas-grekas commentedDec 28, 2016 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
|
GuilhemN commentedDec 28, 2016
@nicolas-grekas I was thinking about a tag returning something similar to the JavaScript |
dunglas commentedDec 28, 2016
+1 for |
TomasVotruba commentedDec 30, 2016 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Just for inspiration from@nette, there is similar tool, that decorates specific classes/types of classes: Seethis article - jump to "Decorator Extension to the Rescue" headline. And this Tweet:https://twitter.com/VotrubaT/status/812802092356276224 I'm amazed, how similar these tools are :) |
grachevko commentedDec 30, 2016
What about add |
TomasVotruba commentedDec 31, 2016
@grachevko How would that look like? From example I understand it's global setup for all services. |
grachevko commentedDec 31, 2016 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
@TomasVotruba not a global. This PR add |
TomasVotruba commentedDec 31, 2016
@grachevko Ah. That's a pity. I was looking forward to get rid of Console, EventSubscriber, FormType etc. tags. I'll work on that Decorator feature then :) |
fabpot commentedJan 7, 2017
👍 |
1 similar comment
dunglas commentedJan 7, 2017
👍 |
9545899 to88b99fbComparefabpot commentedJan 7, 2017
Thank you@nicolas-grekas. |
…ame for "public", "tags" & "autowire" (nicolas-grekas, ogizanagi)This PR was merged into the 3.3-dev branch.Discussion----------[DI] Add "inherit-tags" with configurable defaults + same for "public", "tags" & "autowire"| Q | A| ------------- | ---| Branch? | master| Bug fix? | no| New feature? | yes| BC breaks? | no| Deprecations? | no| Tests pass? | yes| Fixed tickets |#20048| License | MIT| Doc PR | -Instead of making services private by default (#20048), which is going to create a big migration burden that might not be worth it, I'd like to propose the idea of changing the default for the current file.Having a place to redefine some defaults, this can also be used to enable autowiring for a file, making it much lighter in the end.This PR handles defaults for "public", "autowired" and "tags". Not sure the other options need a configurable default. Please comment if you think otherwise.Short example (the feat is more interesting with a longer list of services):```yamlservices: _defaults: public: false autowire: ['_construct', 'set*'] foo: class: Foo``````xml<?xml version="1.0" encoding="utf-8"?><container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/serviceshttp://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <defaults public="false"> <autowire>__construct</autowire> <tag name="foo"/> </defaults> </services></container>```ping@dunglas@weaverryanCommits-------beec1cf [DI] Allow definitions to inherit tags from parent context05f24d5 [DI] Add "defaults" tag to XML services configuration7b4a18b [DI] Add "_defaults" key to Yaml services configuration
chalasr commentedJan 8, 2017
The new |
…gizanagi)This PR was merged into the 3.3-dev branch.Discussion----------[DI] Fixes aliases visibility with and without defaults| Q | A| ------------- | ---| Branch? | master| Bug fix? | yes| New feature? | no| BC breaks? | no| Deprecations? | no| Tests pass? | yes| Fixed tickets |#21071 (comment)| License | MIT| Doc PR | N/ACommits-------f1cc090 [DI] Fixes aliases visibility with and without defaults
…izanagi)This PR was merged into the 3.3-dev branch.Discussion----------[DI] Add Yaml syntax for short services definition| Q | A| ------------- | ---| Branch? | master| Bug fix? | no| New feature? | yes| BC breaks? | no| Deprecations? | no| Tests pass? | yes| Fixed tickets | N/A| License | MIT| Doc PR | todoIn my experience, most (at least, a lot) of the service definitions in an end-application only require the class and constructor arguments.#21133 allows to get rid of the `class` attribute by using the service id.Which means only arguments remain for most use-cases. Hence, we could support this syntax:#### Before:```ymlservices: App\Foo\Bar: arguments: ['@baz', 'foo', '%qux%']```#### After:```ymlservices: App\Foo\Bar: ['@baz', 'foo', '%qux%']```It works especially well along with services `_defaults` introduced in#21071 :```ymlservices: _defaults: public: false autowire: ['set*'] tags: ['serializer.normalizer'] App\Serializer\FooNormalizer: ['@baz', 'foo', '%qux%']```Commits-------83b599c [DI] Add Yaml syntax for short services definition

Uh oh!
There was an error while loading.Please reload this page.
Instead of making services private by default (#20048), which is going to create a big migration burden that might not be worth it, I'd like to propose the idea of changing the default for the current file.
Having a place to redefine some defaults, this can also be used to enable autowiring for a file, making it much lighter in the end.
This PR handles defaults for "public", "autowired" and "tags". Not sure the other options need a configurable default. Please comment if you think otherwise.
Short example (the feat is more interesting with a longer list of services):
ping@dunglas@weaverryan