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] Add#[Autoconfigure] to help define autoconfiguration rules#39804

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

Merged
nicolas-grekas merged 1 commit intosymfony:5.xfromnicolas-grekas:autoconf-attr
Feb 16, 2021

Conversation

@nicolas-grekas
Copy link
Member

@nicolas-grekasnicolas-grekas commentedJan 12, 2021
edited
Loading

QA
Branch?5.x
Bug fix?yes
New feature?no
Deprecations?no
Tickets-
LicenseMIT
Doc PR-

Being inspired by the discussion with@derrabus in#39776.

This PR allows declaring autoconfiguration rules using an attribute on classes/interfaces, eg:
#[Autoconfigure(bind: ['$foo' => 'bar'], tags: [...], calls: [...])]

This should typically be added on a base class/interface to tellhow implementations of such a base type should be autoconfigured. The attribute is parsed when autoconfiguration is enabled, except when a definition has thecontainer.ignore_attributes tag, which allows opting out from this behavior.

As usual, the corresponding rules are applied only to services that have autoconfiguration enabled.

In practice, this means that this enables auto-tagging of all implementations of this interface:

#[Autoconfigure(tags: ['my_tag'])]interface MyInterface {...}

Of course, all auto-configurable settings are handled (calls, bindings, etc.)

This PR adds another attribute:#[AutoconfigureTag()].

It extends#[Autoconfigure] and allows for specifically defining tags to attach by autoconfiguration.

The name of the tag is optional and defaults to the name of the tagged type (typically the FQCN of an interface). This should ease with writing locators/iterators of tagged services.

#[AutoconfigureTag()]interface MyInterface {...}

derrabus, zmitic, and rvanlaak reacted with rocket emoji
@nicolas-grekasnicolas-grekas added this to the5.x milestoneJan 12, 2021
@carsonbotcarsonbot changed the title[DI] Add "#[Autoconfigure]" to tell how a discovered type should be autoconfigured[DependencyInjection] Add "#[Autoconfigure]" to tell how a discovered type should be autoconfiguredJan 12, 2021
@nicolas-grekasnicolas-grekasforce-pushed theautoconf-attr branch 3 times, most recently from8c5ba49 to1e1b86eCompareJanuary 12, 2021 19:11
@ro0NL
Copy link
Contributor

is there any reason for the "auto discovered services only" actually?

@apfelbox
Copy link
Contributor

Quick nitpick question: should the attribute be named#[Autoconfigure] or#[Autoconfigured]? Because the class is autoconfigured, it does not do any configuring itself.

The recently proposed#[Deprecated] attribute in PHP itself is in passive voice as well.

@nicolas-grekas
Copy link
MemberAuthor

Because the class is autoconfigured, it does not do any configuring itself.

I feel like I missed explaining correctly how this works.Yes, this attribute declares a configuration rule for autoconfiguration.

@nicolas-grekasnicolas-grekas changed the title[DependencyInjection] Add "#[Autoconfigure]" to tell how a discovered type should be autoconfigured[DependencyInjection] Add#[Autoconfigure] to help define autoconfiguration rulesJan 13, 2021
@nicolas-grekasnicolas-grekasforce-pushed theautoconf-attr branch 3 times, most recently from3a1e8b6 to5b98e9dCompareJanuary 14, 2021 00:00
@wouterj
Copy link
Member

IIUC, we now have 2 competing PRs here. As far as I know, it was decided that progress continues in#39897? Please correct me if I'm wrong, but otherwise this one should be closed I think.

@nicolas-grekas
Copy link
MemberAuthor

@wouterj this one provides something else. Both should be merged to me in the end. This one before#39897 since it's ready and might be used by#39897 as explained in#39897 (comment)

@nicolas-grekasnicolas-grekasforce-pushed theautoconf-attr branch 2 times, most recently fromafe384e toe66a3baCompareFebruary 6, 2021 09:13
@nicolas-grekas
Copy link
MemberAuthor

/cc @symfony/mergers anyone?

@wouterj
Copy link
Member

wouterj commentedFeb 11, 2021
edited
Loading

As requested, I'll post some of my comment in the other PR (ref:#39897 (comment) ) here:

😃 What I like about this PR is that it reuses the autoconfigure system (using the Yaml file loader seems a bit hacky, but I'm surely not the one to make a decision about that).
😐 What I'm not so sure about is why there is a need to have a userlandAutoconfigure attribute. I personally don't see this need (especially if#39897 will make it, as that implements more specialized and nice userland attributes for this purpose).
I think such a generic attribute opens up a lot of misuse (e.g. in the other PR, it was shown that you can misuse attributes instead of implementing theResetInterface contract).
I feel like it couples attributes directly to DI (which e.g. a@required annotation explicitly avoids).
At last, by having both a generic attribute and more specific attributes (from#39897), we provide more than 1 solution for the same problem. How should we document this? What are the advantages of one over the other?

@nicolas-grekas
Copy link
MemberAuthor

nicolas-grekas commentedFeb 11, 2021
edited
Loading

(using the Yaml file loader seems a bit hacky, but I'm surely not the one to make a decision about that).

What matters here is how one can describe something using an array data structure. YamlLoader does exactly this: turn arrays (from yaml) into actual calls. Here, we just reuse that logic, so that the same array-structures can also be used in attributes. E.g.:

#[Autoconfigure(    calls: ['setFoo' => ['the-args']])]

What I'm not so sure about is why there is a need to have a userland Autoconfigure attribute. I personally don't see this need

All ppl that use_instanceof or$container->registerForAutoconfiguration() have a need for this.
It allows telling to the DI engine how a definition should be autoconfigured, depending on the base types of the class it describes.

especially if#39897 will make it, as that implements more specialized and nice userland attributes for this purpose.

There is a critical difference with#39897: the attribute in this PR allows defining rules that areinherited.#39897 defines attributes that arenot inherited.

That'sTHE critical difference between both PRs, and why they fill a different need.

I think such a generic attribute opens up a lot of misuse (e.g. in the other PR, it was shown that you can misuse attributes instead of implementing the ResetInterface contract).

Can you clarify? To me, it looks like you're arguing against empowering ppl, which I'm sure you aren't.
I must miss something, or I just don't agree :)

I feel like it couples attributes directly to DI (which e.g. a@required annotation explicitly avoids).

I do not understand this "coupling" argument. To me, as I explained in#39776 (comment), there is zero difference between this PR,#39776 or#39897 in this regard.

Maybe you can help me understand what you mean with actual examples of when this "coupling" would happen?

At last, by having both a generic attribute and more specific attributes (from#39897), we provide more than 1 solution for the same problem. How should we document this? What are the advantages of one over the other?

See "the critical difference" I mention above.

@nicolas-grekas
Copy link
MemberAuthor

nicolas-grekas commentedFeb 11, 2021
edited
Loading

How should we document this?

TL;DR of my previous comment:

Note that these two lines are orthogonal.

Copy link
Member

@derrabusderrabus left a comment

Choose a reason for hiding this comment

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

I understand the intention of this generic attribute as a nicer way to configure autoconfiguration rules for userland base types.

Instead of cluttering my kernel with…

$container->registerForAutoconfiguration(MyInterface::class)     ->addTag('my_tag');

… I annotate this rule to my interface instead.

#[Autoconfigure(tags: ['my_tag'])]interface MyInterface {}

Did I get this right?

I think, this is the use case we can agree on. But since attributes are a new feature to most users, it is imperative that we distinguish the use-cases of this PR and#39897 in the documentation.

@nicolas-grekas
Copy link
MemberAuthor

@derrabus you've got it right. I agree about the doc.

derrabus reacted with thumbs up emoji

@nicolas-grekasnicolas-grekas merged commit4d91b8f intosymfony:5.xFeb 16, 2021
@nicolas-grekasnicolas-grekas deleted the autoconf-attr branchFebruary 18, 2021 17:00
nicolas-grekas added a commit that referenced this pull requestMar 16, 2021
…r defining the index and priority of classes found in tagged iterators/locators (nicolas-grekas)This PR was merged into the 5.3-dev branch.Discussion----------[DependencyInjection] Add `#[TaggedItem]` attribute for defining the index and priority of classes found in tagged iterators/locators| Q             | A| ------------- | ---| Branch?       | 5.x| Bug fix?      | no| New feature?  | yes| Deprecations? | no| Tickets       | -| License       | MIT| Doc PR        | -Next to#39804, this PR adds a new `#[TaggedItem]` attribute that ppl can use to define the index of their service classes when they're used in tagged collections (iterators/locators.This replaces the `public static getDefaultName()` and `getDefaultPriority()` methods that ppl could use for this purpose:```php#[TaggedItem(index: 'api.logger', priority: 123)]class MyApiLogger implements LoggerInterface{}```This will ship the corresponding service at index `api.logger`, priority=123 when building locators/iterators.Commits-------252f2ca [DependencyInjection] Add `#[TaggedItem]` attribute for defining the index and priority of classes found in tagged iterators/locators
@fabpotfabpot mentioned this pull requestApr 18, 2021
@kozlice
Copy link

This is a really cool feature, but I've just tried it and there seems to be an issue:

#[Autoconfigure(tags: ['some.tag'])]interface MyServiceInterface {}class MyServiceimplements MyServiceInterface {}$class =newReflectionClass(MyService::class);// That's how RegisterAutoconfigureAttributesPass does it$attributes =$class->getAttributes(Autoconfigure::class, \ReflectionAttribute::IS_INSTANCEOF);// Whoopsie, empty arrayvar_dump($attributes);

Running PHP 8.0.6. Looks like theIS_INSTANCEOF flag doesn't do what it is supposed to do.

@nicolas-grekas
Copy link
MemberAuthor

You might have missed how this works. I can't really help because I don't know what you want todo, but of course, requesting the attributes on classMyService won't list you the attributes on interfaceMyServiceInterface...

@kozlice
Copy link

@nicolas-grekas Yeah, I might've misunderstood something.

The announcement in blog says thatAutoconfigure can be used to replaceregisterForAutoconfiguration for auto-tagging by interface.

So, I've tried this:

#[Autoconfigure(tags: ['some.tag'])]interface ServiceInterface {}class ServiceAimplements ServiceInterface {}class ServiceBimplements ServiceInterface {}
services:_defaults:autowire:trueautoconfigure:trueApp\ServiceA:~App\ServiceB:~

And I was expecting both services to be tagged, but they are not.

@nicolas-grekas
Copy link
MemberAuthor

Please open an issue if you think you found a bug, with a reproducer ideally.

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@OskarStarkOskarStarkOskarStark left review comments

@jderussejderussejderusse approved these changes

@derrabusderrabusderrabus approved these changes

@chalasrchalasrchalasr approved these changes

+1 more reviewer

@ro0NLro0NLro0NL left review comments

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Projects

None yet

Milestone

5.4

Development

Successfully merging this pull request may close these issues.

10 participants

@nicolas-grekas@ro0NL@apfelbox@wouterj@kozlice@jderusse@OskarStark@derrabus@chalasr@carsonbot

[8]ページ先頭

©2009-2025 Movatter.jp