Skip to content
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

[DI] Allow autowiring by type + parameter name #28234

Merged
merged 1 commit into from Aug 24, 2018

Conversation

Projects
None yet
5 participants
@nicolas-grekas
Copy link
Member

commented Aug 20, 2018

Q A
Branch? master
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets -
License MIT
Doc PR symfony/symfony-docs#10206

In #27165, we introduced the possibility to bind by type+name:

bind:
    Psr\Log\LoggerInterface $myLogger: @monolog.logger.my_logger

But we forgot about aliases. For consistency, they could and should allow doing the same. More importantly, this will open up interesting use cases where bundles could provide default values for typed+named arguments (using the new ContainerBuilder::registerAliasForArgument() method). E.g:

services:
    Psr\Cache\CacheItemPoolInterface $appCacheForecast: @app.cache.forecast

Works also for controller actions and service subscribers (using the real service id as the key).

@nicolas-grekas

This comment has been minimized.

Copy link
Member Author

commented Aug 21, 2018

Now with a new ContainerBuilder::registerAliasForArgument() method used in FrameworkExtension to create such aliases for cache pool, lock resources and messenger buses.
E.g. type hint public function __construct(MessageBusInterface $commandBus) to get the bus declared as "command_bus" in your config.

@weaverryan
Copy link
Member

left a comment

I love this. It solves the last weird autowiring situation in an automated way: classes that have multiple services (cache, log, etc).

We'll need to update debug:autowiring to show this. We want to update it anyways to be a bit more "helpful" in general. We need to do that for 4.2.

@@ -1613,6 +1623,8 @@ private function registerCacheConfiguration(array $config, ContainerBuilder $con
$definition->addTag('cache.pool', $pool);
$container->setDefinition($name, $definition);
$container->registerAliasForArgument($name, CacheInterface::class);
$container->registerAliasForArgument($name, CacheItemPoolInterface::class);

This comment has been minimized.

Copy link
@weaverryan

weaverryan Aug 21, 2018

Member

Will this work ok for the $name = '.'.$name.'.inner'; cases above?

This comment has been minimized.

Copy link
@nicolas-grekas

nicolas-grekas Aug 21, 2018

Author Member

good catch, moved up in the foreach!

/**
* Registers an alias for autowiring the passed id using named arguments.
*/
public function registerAliasForArgument(string $id, string $type, string $name = null): Alias

This comment has been minimized.

Copy link
@weaverryan

weaverryan Aug 21, 2018

Member

Can we doc the arguments? Because we normalize them into lower-camel case, I think it IS worth saying what each argument means

This comment has been minimized.

Copy link
@nicolas-grekas

nicolas-grekas Aug 21, 2018

Author Member

I added a docblock description, good enough?

@nicolas-grekas nicolas-grekas force-pushed the nicolas-grekas:di-arg-alias branch from 27b52c5 to 414e25a Aug 21, 2018

@weaverryan
Copy link
Member

left a comment

+1 for me. But, this makes updating debug:autowiring an absolute must for 4.2.

@sroze

sroze approved these changes Aug 22, 2018

Copy link
Member

left a comment

That's super cool. Though, could you add a test for a service named some_service (which is claimed to work on the PhpDoc but tests are only using some.service)?

@@ -1509,6 +1517,8 @@ private function registerMessengerConfiguration(array $config, ContainerBuilder
if ($busId === $config['default_bus']) {
$container->setAlias('message_bus', $busId)->setPublic(true);
$container->setAlias(MessageBusInterface::class, $busId);
} else {
$container->registerAliasForArgument($busId, MessageBusInterface::class);

This comment has been minimized.

Copy link
@sroze

sroze Aug 22, 2018

Member

Any reason why we wouldn't register every bus, including the one that has been chosen as the default? The question also works for the lock (because in cache, all of them or registered)

This comment has been minimized.

Copy link
@nicolas-grekas

nicolas-grekas Aug 22, 2018

Author Member

Yes: because the default service is already the one wired... by default :)

@sroze

This comment has been minimized.

Copy link
Member

commented Aug 22, 2018

I really like it!

@nicolas-grekas nicolas-grekas force-pushed the nicolas-grekas:di-arg-alias branch from 82adeb1 to c0b8f53 Aug 23, 2018

@nicolas-grekas

This comment has been minimized.

Copy link
Member Author

commented Aug 23, 2018

add a test for a service named some_service

done as ContainerBuilderTest::testRegisterAliasForArgument()

@nicolas-grekas nicolas-grekas merged commit c0b8f53 into symfony:master Aug 24, 2018

3 checks passed

continuous-integration/appveyor/pr AppVeyor build succeeded
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
fabbot.io Your code looks good.
Details

nicolas-grekas added a commit that referenced this pull request Aug 24, 2018

feature #28234 [DI] Allow autowiring by type + parameter name (nicola…
…s-grekas)

This PR was merged into the 4.2-dev branch.

Discussion
----------

[DI] Allow autowiring by type + parameter name

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | -
| License       | MIT
| Doc PR        | symfony/symfony-docs#10206

In #27165, we introduced the possibility to bind by type+name:
```yaml
bind:
    Psr\Log\LoggerInterface $myLogger: @monolog.logger.my_logger
```

But we forgot about aliases. For consistency, they could and should allow doing the same. More importantly, this will open up interesting use cases where bundles could provide default values for typed+named arguments (using the new `ContainerBuilder::registerAliasForArgument()` method). E.g:
```yaml
services:
    Psr\Cache\CacheItemPoolInterface $appCacheForecast: @app.cache.forecast
```
Works also for controller actions and service subscribers (using the real service id as the key).

Commits
-------

c0b8f53 [DI] Allow autowiring by type + parameter name

@nicolas-grekas nicolas-grekas deleted the nicolas-grekas:di-arg-alias branch Aug 24, 2018

nicolas-grekas added a commit that referenced this pull request Oct 29, 2018

feature #28970 [FrameworkBundle] make debug:autowiring list useful se…
…rvices and their description (nicolas-grekas)

This PR was merged into the 4.2-dev branch.

Discussion
----------

[FrameworkBundle] make debug:autowiring list useful services and their description

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

This PR closes #27207: we don't need "semantics" anymore. 4.2 has everything already to allow us to separate useful services from the other ones: any autowireable *alias* **is** a useful service!
Add autowiring by type + parameter name (#28234) and the story is done: we can easily hint people about which features their bundles provide, without being polluted by for-wiring-only services.

Here is a screenshot running this command(before I excluded the aliases for $cacheApp and $cacheSystem):
![image 3](https://user-images.githubusercontent.com/243674/47437006-f41f4380-d7a7-11e8-9f76-7f23e9193ce8.png)

ping @weaverryan as we drafted that together.
Fixes a few issues found meanwhile.
That should definitely go in 4.2.

Commits
-------

56aab09 [FrameworkBundle] make debug:autowiring list useful services and their description

@nicolas-grekas nicolas-grekas modified the milestones: next, 4.2 Nov 1, 2018

This was referenced Nov 3, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.