Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[DependencyInjection] Anonymous services in PHP DSL#24632

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

Conversation

@unkind
Copy link
Contributor

@unkindunkind commentedOct 19, 2017
edited
Loading

QA
Branch?4.1
Bug fix?no
New feature?enhancement for fluent PHP configs
BC breaks?no
Deprecations?no
Tests pass?yes
Fixed tickets#24493
LicenseMIT
Doc PRnot yet

See#24493:

$s->anonymous(SendEmailForRegisteredUser::class)->tag('listener');

@unkind
Copy link
ContributorAuthor

unkind commentedOct 19, 2017
edited
Loading

I didn't fix all the tests yet (is there any script to update all autogenerated DI-fixtures?), need feedback. ping@nicolas-grekas

UPD: target branch is incorrect. Anyway, any chance to merge it in 3.4? If so, I'll reopen PR.

@unkindunkindforce-pushed theenhancement-anonymous-services-fluent-php branch 7 times, most recently from55997aa to02bf763CompareOctober 19, 2017 18:08
@nicolas-grekasnicolas-grekas added this to the3.4 milestoneOct 19, 2017
@chalasrchalasr changed the base branch frommaster to3.4October 19, 2017 19:26
@unkindunkind changed the title[DependencyInjection] Anonymous services & decorates()[DependencyInjection] Anonymous services & decoratorsOct 19, 2017
Copy link
Member

@nicolas-grekasnicolas-grekas left a comment
edited
Loading

Choose a reason for hiding this comment

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

I think I'm 👎: this will introduce a non trivial amount of complexity (it's broken already), when the current way just works (just give that decorator a name.)

*/
finalpublicfunctionargs(array$arguments)
{
$arguments =array_map(

Choose a reason for hiding this comment

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

Ihe inner can be injected anywhere, not only in the constructor, and can be nested also. The logic should be in AbstractConfigurator::processValue() (but it's not trivial to do so).

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

and can be nested also

What do you mean?

The logic should be in AbstractConfigurator::processValue() (but it's not trivial to do so)

It is still in dev branch, later will be much harder to fix it. Probably, it's not the only case when we needDefinition object there.

Choose a reason for hiding this comment

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

the inner service doesn't have to be injected as an argument: it can be nested in an array, which itself is passed as argument (constructor, or setter, or property in fact.)

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

the inner service doesn't have to be injected as an argument: it can be nested in an array, which itself is passed as argument (constructor, or setter, or property in fact.)

It just requires to tweakAbstractConfigurator::processValue() to make it work, doesn't it?

Choose a reason for hiding this comment

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

it should (but I'm still not sure it's worth the added complexity)

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

It there any reason why it is static? As I can see,AbstractConfigurator contains link to thedefinition. I'm not big fan of it, but it's cheap solution.

Choose a reason for hiding this comment

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

it's used infunction iterator(array $values)

);
}

returnnewReferenceConfigurator($decorated[1] ?$decorated[1] :$this->id .'.inner');

Choose a reason for hiding this comment

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

".inner" is not hardcoded when decorating services, see "renamedId".

Copy link
ContributorAuthor

@unkindunkindOct 19, 2017
edited
Loading

Choose a reason for hiding this comment

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

I don't get it.$decorated[1] contains value ofrenamedId. I use.inner suffix when user didn't specifyrenamedId.

Choose a reason for hiding this comment

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

oh ok!

@unkind
Copy link
ContributorAuthor

I think I'm 👎: this will introduce a non trivial amount of complexity (it's broken already), when the current way just works (just give that decorator a name.)

What about just anonymous services without decorators?

@nicolas-grekas
Copy link
Member

What about just anonymous services without decorators?

I would do it without the "anonymous" helper:->set(null, Fqcn::class)

@unkind
Copy link
ContributorAuthor

I would do it without the "anonymous" helper

Well, a lot (probably, most) of my services are anonymous: listeners, command handlers, API controllers, console commands, cache/monitoring/logging decorators. I can useset(SendEmailForRegisteredUserListener::class, ...) for most of them, but they include namespace and service name becomes very long. On other hand, typingset(null, ...) again and again doesn't make me happy as well.

@nicolas-grekas
Copy link
Member

nicolas-grekas commentedOct 19, 2017
edited
Loading

My fear is that ppl will get confused when reading
->set(Foo::class)
vs
->anonymous(Foo::class)
the difference is not obvious if you're not used to anonymous services (how many of us are, of many new comers...)
->set(null, Foo::class) on the contrary is "more" different than->set(Foo::class)

And I'm also fearing that writing actually might become more confusing: "anonymous" would become a new item on the autocompletion list, which ppl might have a hard time figure out what it means (because it's not that common) - and even scarier: ppl doing the mistake of selecting the wrong set/anonymous choice might have an even harder time figuring out their mistake.

@unkind
Copy link
ContributorAuthor

the difference is not obvious if you're not used to anonymous services
And I'm also fearing that writing actually might become more confusing

Let them learn the difference. They won't hurt themselves, it's not a gun.

(how many of us are, of many new comers...)

I think most of us have such services in our codebases, we probably just don't realize it. It's yet another reason to make it explicit in my opinion.

@unkindunkindforce-pushed theenhancement-anonymous-services-fluent-php branch 3 times, most recently fromf304759 to766ceb3CompareOctober 20, 2017 20:46
@unkindunkind changed the title[DependencyInjection] Anonymous services & decorators[DependencyInjection] Anonymous servicesOct 20, 2017
@unkind
Copy link
ContributorAuthor

I've removed decorators, tests are OK except some unrelated ones.

Let's focus on theanonymous() helper. Do you really want to remove it? I'd like to see it as explicit way to register a service, I really don't like nullables, it's almost always better to introduce new straightforward method. I also really doubt it's sort of "forbidden knowledge" that may bring any problems to people. They'd rather discover something new for themselves.

@unkind
Copy link
ContributorAuthor

unkind commentedOct 20, 2017
edited
Loading

Offtopic:

just give that decorator a name

This annoys in the same way as requirement to specify name for "anonymous" services: I don't need it. Considering we have name convention for service names likegame.infrastructure.players_qs_memcache_decorator.inner, it becomes a problem. We also have sometimes 3-4 similar services with decorators, so I copy-paste definitions and trying to find the difference in names which I don't even need, ugh.

@nicolas-grekasnicolas-grekas modified the milestones:3.4,4.1Oct 21, 2017
@nicolas-grekas
Copy link
Member

I'm still really unsold on the topic, if anything,->set(null, Foo::class) should be the way to IMHO.
Services don'thave to be anonymous. Giving them a name is fine (esp. when the name is automatically set as is now.)

@unkind
Copy link
ContributorAuthor

@nicolas-grekas it looks like astraw man for me: I didn't say that serviceshave to be anonymous. Just many of themcould be. Giving name is fine, but sometimes is totally pointless like rituals.

->set(null, Foo::class)

Giving a name for this construction is fine, isn't it?->set(null, Foo::class) is WTF syntax and it's harder to google it.

The whole discussion is about explicit vs implicit syntax for the same concept. I don't understand your point why this kind of syntax should be implicit.

@nicolas-grekas
Copy link
Member

nicolas-grekas commentedNov 26, 2017
edited
Loading

Oh! :)
could be would need a reason. When doing->set(Foo::class) is actually fine, I really don't see benefit of doing->anonymous(Foo::class). The first providing a name is a side effect that benefits everyone when needing a name, and doesn't hurt anyone when a name is actually not needed. That's my reasoning. Just let SF give a name for you, and ignore it if you don't need it.
The only case where the name is actually boilerplate if when you need several services implemented by the same class. Which is a case where you have to type some configuration anyway, and doing->set(null, Foo::class) would just work and not look like impossible boilerplate IMHO.

@unkind
Copy link
ContributorAuthor

It should be quite easy to define your own DSL, by creating a different set of configurator classes, and type-hinting for them in the closure.

What do you think of decorators forContainerConfigurator?

@@ -23,6 +25,16 @@ use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigura  */ class PhpFileLoader extends FileLoader {+    private $configuratorDecorator;++    public static function withConfiguratorDecorator(ContainerBuilder $container, FileLocatorInterface $locator, callable $configuratorDecorator): PhpFileLoader+    {+        $loader = new self($container, $locator);+        $loader->configuratorDecorator = $configuratorDecorator;++        return $loader;+    }+     /**      * {@inheritdoc}      */@@ -44,7 +56,13 @@ class PhpFileLoader extends FileLoader         $callback = $load($path);         if ($callback instanceof \Closure) {-            $callback(new ContainerConfigurator($this->container, $this, $this->instanceof, $path, $resource), $this->container, $this);+            $configurator = new ContainerConfigurator($this->container, $this, $this->instanceof, $path, $resource);++            if ($this->configuratorDecorator) {+                $configurator = call_user_func($this->configuratorDecorator, $configurator);+            }++            $callback($configurator, $this->container, $this);         }

@ro0NL
Copy link
Contributor

set(null, Foo::class) doesnt work in 4.0 duestring $id type :) which is also the phpdoc in 3.4, this is actually consistent with the current loaders right.

Anyway, just walked into this trying to register a event listener twice. Now in a codebase full ofset(Fqcn::class) theset(null, Fqcn::class) (if it worked) looks a bit odd... but im really thinking of a good ID value now 🤔 (the "naming is hard" issue also counts a bit IMHO).

@unkind
Copy link
ContributorAuthor

naming is hard

Especially when you don't need a name (anonymous/lambda functions is a very close example).

@nicolas-grekas
Copy link
Member

nicolas-grekas commentedDec 29, 2017
edited
Loading

set(null, Foo::class) doesnt work in 4.0 due string $id type

which is not an issue since the method is final, so can be changed without any BC break

@ro0NL
Copy link
Contributor

Hm looking at failing tests locally

+    :\n+        class: App\BarService\n+        public: true\n

that's bad right? :)

@unkind
Copy link
ContributorAuthor

@ro0NL if you mean my branch, it's possible if you merged with 3.4/master becauseContainerBuilderTest was changed (GitHub shows the conflict). I could resolve it, but I don't understand the state of PR.

Do I understand correctly that in order to merge it I have to replace->anonymous() with->set(null, ...)?

@ro0NL
Copy link
Contributor

right. I tested on 3.4 :) i thought it worked today already. If we can settle withset(null, Fqcn::class) im fine 👍

@unkind
Copy link
ContributorAuthor

@nicolas-grekas can you change base branch on master?

@curry684
Copy link
Contributor

You can do it yourself with theedit button at the top of the issue.

@unkindunkind changed the base branch from3.4 tomasterJanuary 4, 2018 01:31
@unkind
Copy link
ContributorAuthor

@curry684 thanks, didn't know it.

@nicolas-grekasnicolas-grekasforce-pushed theenhancement-anonymous-services-fluent-php branch fromd709412 to8b6945dCompareJanuary 22, 2018 19:30
@nicolas-grekasnicolas-grekas changed the title[DependencyInjection] Anonymous services[DependencyInjection] Anonymous services in PHP DSLJan 22, 2018
@nicolas-grekasnicolas-grekasforce-pushed theenhancement-anonymous-services-fluent-php branch from8b6945d to2348c11CompareJanuary 22, 2018 19:32
Copy link
Member

@nicolas-grekasnicolas-grekas left a comment

Choose a reason for hiding this comment

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

(@unlinkd FYI, I pushed some changes on your fork, was quicker for me this way. Ready on my side thank you.)

@unkind
Copy link
ContributorAuthor

OK, looks good.

@fabpot
Copy link
Member

Cannot be merged as tests are broken.

@nicolas-grekasnicolas-grekasforce-pushed theenhancement-anonymous-services-fluent-php branch from2348c11 toee42276CompareJanuary 23, 2018 06:58
@nicolas-grekas
Copy link
Member

Tests fixed, should be green in a few minutes.

@fabpot
Copy link
Member

Thank you@unkind.

sstok reacted with hooray emoji

@fabpotfabpot merged commitee42276 intosymfony:masterJan 23, 2018
fabpot added a commit that referenced this pull requestJan 23, 2018
…nkind)This PR was merged into the 4.1-dev branch.Discussion----------[DependencyInjection] Anonymous services in PHP DSL| Q             | A| ------------- | ---| Branch?       | 4.1| Bug fix?      | no| New feature?  | enhancement for fluent PHP configs| BC breaks?    | no| Deprecations? | no| Tests pass?   | yes| Fixed tickets |#24493| License       | MIT| Doc PR        | not yetSee#24493:```php$s->anonymous(SendEmailForRegisteredUser::class)->tag('listener');```Commits-------ee42276 [DI] Add way to register service with implicit name using the PHP DSL
@ro0NL
Copy link
Contributor

Nice one@unkind. Thx super useful :)

@fabpotfabpot mentioned this pull requestMay 7, 2018
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@fabpotfabpotfabpot approved these changes

@nicolas-grekasnicolas-grekasnicolas-grekas approved these changes

+1 more reviewer

@TobionTobionTobion left review comments

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Projects

None yet

Milestone

4.1

Development

Successfully merging this pull request may close these issues.

10 participants

@unkind@nicolas-grekas@Tobion@weaverryan@chalasr@javiereguiluz@ro0NL@curry684@fabpot@carsonbot

[8]ページ先頭

©2009-2025 Movatter.jp