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

[FrameworkBundle] [DI] Automatically add "setLogger" method call.#24973

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

Closed
GaryPEGEOT wants to merge7 commits intosymfony:masterfromGaryPEGEOT:feature/logger-aware-di
Closed

[FrameworkBundle] [DI] Automatically add "setLogger" method call.#24973

GaryPEGEOT wants to merge7 commits intosymfony:masterfromGaryPEGEOT:feature/logger-aware-di

Conversation

@GaryPEGEOT
Copy link
Contributor

@GaryPEGEOTGaryPEGEOT commentedNov 15, 2017
edited
Loading

QA
Branch?master
Bug fix?no
New feature?yes
BC breaks?no
Deprecations?no
Tests pass?yes
Fixed tickets
LicenseMIT
Doc PR

Automatically addsetLogger method call to any service that implementsPsr\Log\LoggerAwareInterface.

Not sure if this belong to FrameworkBundle or MonologBundle.

timonf and ro0NL reacted with thumbs up emoji
@nicolas-grekasnicolas-grekas added this to the4.1 milestoneNov 15, 2017
@ro0NL
Copy link
Contributor

enable byautoconfigure: true?

chalasr reacted with thumbs up emoji

@chalasr
Copy link
Member

Belongs to monolog-bundle to me.

@ogizanagi
Copy link
Contributor

ogizanagi commentedNov 15, 2017
edited
Loading

Looks good to me in the FrameworkBundle, as we now have the default logger from HttpKernel registered aslogger service if monolog (or any other one registering alogger service) isn't installed.

Koc reacted with thumbs up emoji

}

$refl =new \ReflectionClass($definition->getClass());
if ($refl->implementsInterface(LoggerAwareInterface::class) && !$definition->hasMethodCall('setLogger')) {
Copy link
Contributor

@stloydstloydNov 15, 2017
edited
Loading

Choose a reason for hiding this comment

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

Maybe:

if ($definition->hasMethodCall('setLogger')) {continue;}if (\in_array(LoggerAwareInterface::class,class_implements($definition->getClass()),true)) {}

$reference =newReference('logger');

foreach ($container->getDefinitions()as$definition) {
if (!class_exists($definition->getClass()) || !$definition->isAutoconfigured()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

|| $definition->hasMethodCall('setLogger') here?

continue;
}

$refl =new \ReflectionClass($definition->getClass());
Copy link
Contributor

Choose a reason for hiding this comment

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

$container->getReflectionClass() i guess =/

class LoggerAwarePassTestextends TestCase
{
/**
* @covers \Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\LoggerAwarePass::process()
Copy link
Contributor

Choose a reason for hiding this comment

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

dont think this is needed really.

$reference =newReference('logger');

foreach ($container->getDefinitions()as$definition) {
if (!class_exists($definition->getClass()) || !$definition->isAutoconfigured()) {
Copy link
Member

Choose a reason for hiding this comment

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

no reason to skip autoconfigured definitions. If we wantautoconfigure to leverage this, the compiler pass should only process definitions with a given tag, and that tag+LoggerAwareInterface should be registered for autoconfiguration (seehttps://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php#L269).

continue;
}

$refl =new \ReflectionClass($definition->getClass());
Copy link
Member

Choose a reason for hiding this comment

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

should use$container->getReflectionClass() and be done earlier, replacing theclass_exists check by!$refl and probably throwing in case the check passes. See e.g.https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Console/DependencyInjection/AddConsoleCommandPass.php#L55


foreach ($container->getDefinitions()as$definition) {
$class =$definition->getClass();
if (!class_exists($class) || !$definition->isAutoconfigured() ||$definition->hasMethodCall('setLogger')) {
Copy link
Member

@chalasrchalasrNov 15, 2017
edited
Loading

Choose a reason for hiding this comment

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

If we wantautoconfigure to leverage this, the compiler pass should only process definitions with a given tag, and that tag+LoggerAwareInterface should be registered for autoconfiguration (seehttps://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php#L269).

Copy link
Member

Choose a reason for hiding this comment

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

!class_exists should be replaced by!$refl

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

About autoconfiguration, should I add tag in Framework extension (likelogger.aware?) or skip this checking and add the method call anyway ?

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.

Wait, we don't need that compiler pass at all.
If we want to provide the behavior when autoconfiguration is on, we should just call$container->registerForAutoconfiguration(LoggerAwareInterface::class)->addMethodCall('setLogger', array(new Reference(LoggerInterface::class))) in some DI extension.

@GaryPEGEOT
Copy link
ContributorAuthor

Shouldn't we check that method call ins't already called explicitly ?

@chalasr
Copy link
Member

@nicolas-grekas Actually I think adding method calls to autoconfigure instanceofs is forbiddenhttps://github.com/symfony/symfony/blob/master/src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php#L37, isn't it? Should we remove that restriction?

@nicolas-grekas
Copy link
Member

Calling a setter twice is not an issue to me so not really a pb.
And yes, we should remove the restriction in place.

@chalasr
Copy link
Member

@GaryPEGEOT Can you replace the removed test by a new one ensuring that method calls are handled?

ro0NL reacted with thumbs up emoji

->addTag('validator.initializer');

$container->registerForAutoconfiguration(LoggerAwareInterface::class)
->addMethodCall('setLogger',array(newReference(LoggerInterface::class)));
Copy link
Contributor

@ro0NLro0NLNov 15, 2017
edited
Loading

Choose a reason for hiding this comment

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

Calling a setter twice is not an issue to me so not really a pb.

It would be a WTF no? (who's winning here?) Requires to move your definition outside the current file/context at least... not sure that justifies our technical implem, which is correct; weadd a method call. But being a setter that messes things up.

Also not sure it justifies aaddMethodCallOnce feat., perhaps as 2nd arg?

@GaryPEGEOT
Copy link
ContributorAuthor

@nicolas-grekas Actually autoconfigured calls seems not to be working out of the box (Or I'm missing something.):

/**     * Test that autoconfigured calls are handled gracefully.     */publicfunctiontestProcessForAutoconfiguredCalls()    {$container =newContainerBuilder();$container->registerForAutoconfiguration(LoggerAwareInterface::class)->addMethodCall('setLogger')->addTag('foo');$def =$container->register(\get_class($this->createMock(LoggerAwareInterface::class)));$this->assertFalse($def->hasTag('foo'),'Definition shouldn\'t have tags yet.');// Passes$this->assertFalse($def->hasMethodCall('setLogger'),'Definition shouldn\'t have method call yet.');// Passes        (newResolveInstanceofConditionalsPass())->process($container);$this->assertTrue($def->hasTag('foo'),'Definition should have "foo" tag.');// Passes$this->assertTrue($def->hasMethodCall('setLogger'),'Definition should have "setLogger" method call.');// Fail    }

And I see potential problems for calling set twice, if by example, method is overrided for any reason:

/**     * Sets a logger instance on the object.     *     * @param LoggerInterface $logger     * @param string          $channel Which channel to use     *     * @return void     */publicfunctionsetLogger(LoggerInterface$logger,string$channel =null)    {// TODO: Implement setLogger() method.    }

Here second parameter will be called with default param, so not necessary the expected behavior.

Compiler pass with tagged services seems to be the best option to me.

@nicolas-grekas
Copy link
Member

Actually autoconfigured calls seems not to be working out of the box (Or I'm missing something.):
And I see potential problems for calling set twice, if by example, method is overrided for any reason

I'm OK to agree with that. That makes me wonder we should make that work in fact. The current exception in place that prevents using setters was put in place exactly because we didn't bother fixing those topic at the time.

But I would definitely prefer merging a PR that fixes that, which would provide high generality to the feature, vs merging a hardcoded adhoc alternative. The compiler pass as is could really well be part of a third party bundle meanwhile if you really want it.

@weaverryan
Copy link
Member

This makes sense. But this still requires the user to add the setLogger method. A better DX would be to add a new LoggerTrait with ‘@required’ above the setLogger method.

@ogizanagi
Copy link
Contributor

ogizanagi commentedNov 16, 2017
edited
Loading

But this still requires the user to add the setLogger method

There is already aLoggerAwareTrait part of thepsr/log package.

@GaryPEGEOT
Copy link
ContributorAuthor

I made a separate MR#24996 to allow auto-configured method calls

@nicolas-grekas
Copy link
Member

Closing in favor of#24996, thanks@GaryPEGEOT for taking over.

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

Reviewers

@chalasrchalasrchalasr requested changes

@nicolas-grekasnicolas-grekasnicolas-grekas requested changes

+2 more reviewers

@ro0NLro0NLro0NL left review comments

@stloydstloydstloyd requested changes

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.

8 participants

@GaryPEGEOT@ro0NL@chalasr@ogizanagi@nicolas-grekas@weaverryan@stloyd@carsonbot

[8]ページ先頭

©2009-2025 Movatter.jp