Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[DI] Autowire arguments that are container parameters #21699

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
javiereguiluz opened this issue Feb 21, 2017 · 15 comments
Closed

[DI] Autowire arguments that are container parameters #21699

javiereguiluz opened this issue Feb 21, 2017 · 15 comments
Labels
DependencyInjection Feature RFC RFC = Request For Comments (proposals about features that you want to be discussed)

Comments

@javiereguiluz
Copy link
Member

Q A
Bug report? no
Feature request? yes
BC Break report? no
RFC? yes
Symfony version 3.3

These days we're updating the Symfony Demo app to use the new service configuration proposed for Symfony 3.3. See https://github.com/symfony/symfony-demo/pull/483/files

One of the things I like the least is this config:

services:
    AppBundle\Twig\AppExtension:
        $locales: '%app_locales%'

    AppBundle\EventListener\RedirectToPreferredLocaleSubscriber:
        $locales: '%app_locales%'

    AppBundle\EventListener\CommentNotificationSubscriber:
        $sender: '%app.notifications.email_sender%'

Having to create that boring config just to pass some container parameters destroys the purpose of this new config being RAD, etc.

Proposal

Would it make any sense to "autowire the parameters"?

Before

class AppExtension extends \Twig_Extension
{
    // ...

    public function __construct(Markdown $parser, $locales)
    {
        // ...
    }

    // ...
}
services:
    AppBundle\Twig\AppExtension:
        $locales: '%app_locales%'

After

class AppExtension extends \Twig_Extension
{
    // ...

    public function __construct(Markdown $parser, $locales = '%app_locales%')
    {
        // ...
    }

    // ...
}
@javiereguiluz javiereguiluz added DependencyInjection Feature RFC RFC = Request For Comments (proposals about features that you want to be discussed) labels Feb 21, 2017
@nicolas-grekas
Copy link
Member

Unless I didn't understand well, this has been tried in #20738 and abandoned.

@nicolas-grekas
Copy link
Member

nicolas-grekas commented Feb 21, 2017

Hum, that's not exactly the same - then I have an objection: the class is not usable anymore without Symfony's DIC, which is the one supposed to resolve the %app_locales%.
An annotation would be better, by providing decoupling.

@GuilhemN
Copy link
Contributor

What about using named arguments like that?

services:
    AppBundle\Controller\:
        resource: '../../src/AppBundle/{EventListener,Form/Type,Security,Twig,Utils}'
        arguments:
            $locales: '%app_locales%'
            $sender: '%app.notifications.email_sender%'

@GuilhemN
Copy link
Contributor

Oops looks like it's not possible... Maybe we should allow it then?

@nicolas-grekas
Copy link
Member

@GuilhemN see https://github.com/symfony/symfony/projects/2#card-1770476 - which to be made to work should apply these conditionally

@GuilhemN
Copy link
Contributor

What do you mean by "conditionally"?

@nicolas-grekas
Copy link
Member

Dunno yet, this is only a project card, needs more thought :)
We could also handle a conditional syntax, eg. $?locales: '%app_locales%'

@GuilhemN
Copy link
Contributor

Ok I'll give it a try, seems great :)

@linaori
Copy link
Contributor

linaori commented Feb 21, 2017

While this may seem like a nice solution, there's a few drawbacks:

  • What if you want an int? You'll never be able to type-hint that
  • What if the value was not found with auto-wiring? I will end up with %app_locales%
public function __construct(Markdown $parser, $locales = '%app_locales%');

@magarzon
Copy link

What about a custom annotation?

Makes sense? It's something that I can't see against using annotation for this?

@dunglas
Copy link
Member

dunglas commented Feb 26, 2017

@magarzon I'm not a fond of using (non-standard) annotations for DI: #21103 (comment)

But while this PR is nice, I don't like having to add Symfony specific syntaxes ('%locales%') in the code itself, the code (especially in a service) should be framework agnostic. From that POV, #20738 is better (IMO).

@TomasVotruba
Copy link
Contributor

TomasVotruba commented Dec 9, 2017

With bold news in Symfony 3.3 like PSR-4 service autodiscovery, I think this makes more sense to current coding context now.

Why? Because I cannot use this awesome PSR-4 autodiscovery on most of my services :(

Instead, I have to write them manually all one by one.

parameters:
    twitter_name: 'VotrubaT'
    site_ur: 'https://tomasvotruba.com'
    source_directory: '%kernel.project_dir%/../../../source'
    minimal_gap_in_days: 4 # how many days to wait before publishing another Tweet

    twitter_consumer_key: "..."
    twitter_consumer_secret: "..."
    twitter_oauth_access_token: "..."
    twitter_oauth_access_token_secret: "..."

services:
    TomasVotruba\Website\TweetPublisher\PostTweetsProvider:
        arguments:
            - '%site_url%'
            - '%source_directory%'

    TomasVotruba\Website\TweetPublisher\PostsProvider:
        arguments:
            - '%source_directory%'

    TomasVotruba\Website\TweetPublisher\TwitterApi\TwitterApiWrapper:
        arguments:
            - '%twitter_name%'

    TomasVotruba\Website\TweetPublisher\TweetPublisher:
        public: true # for bin/tweet-new-posts container fetch
        arguments:
            - '%minimal_gap_in_days%'

    # Twitter API
    TomasVotruba\Website\TweetPublisher\TwitterApi\TwitterApiFactory:
        arguments:
            - '%twitter_consumer_key%'
            - '%twitter_consumer_secret%'
            - '%twitter_oauth_access_token%'
            - '%twitter_oauth_access_token_secret%'

I'd love something like this

  • explicit
  • time-saving
  • typo-proof
  • make use of PSR-4 way
services:
    _defaults:
        autowire_parameters: true

    TomasVotruba\Website\TweetPublisher\:
        resource: ../

What do you think?

@nicolas-grekas
Copy link
Member

You can already use bindings https://symfony.com/blog/new-in-symfony-3-4-local-service-binding
Or use the parameter bag as a service in 4.1 since #25288.

@TomasVotruba
Copy link
Contributor

Wow, thanks! πŸ‘

I never thought that could be used this way, even though I've read the post.

Also ParamBag as service is great, I have the same bundle for ages πŸ‘

@TomasVotruba
Copy link
Contributor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
DependencyInjection Feature RFC RFC = Request For Comments (proposals about features that you want to be discussed)
Projects
None yet
Development

No branches or pull requests

7 participants