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

Skip to content

[DependencyInjection] Define default priority inside service class #31943

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
wants to merge 13 commits into from

Conversation

pcabreus
Copy link

@pcabreus pcabreus commented Jun 7, 2019

Q A
Branch? 4.4 for features
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets #...
License MIT

With autoconfigure functions we don't have to do much to inject tagged services into a collector using interfaces, using !tagged is the easy way. But if we need some order we have to use priority, the problem is that priority only can be set by configuration file when it is a simple value.
This PR take a look if the static method getDefaultPriority exists in the service class and return its default value for the service instead of current 0 by defualt.

Example of a service with default priority:

<?php
namespace App;
use App\ServiceTagged;
class Service implement ServiceTagged
{
    public static function getDefaultPriority(): int
    {
        return 50; //This will be the default priority if it's not defined in a configuration file
    }
}
?>

PD: First PR please by nice!

With autoconfigure functions we don't have to do anything to inject tagged services into a collector using interfaces to define tags. But if we need some order we have to use priority, the problem is that priority only can be set by configuration file when it is a simple value.
With this change you could instead of put 0 by defualt take a look if the static method `getDefaultPriority` exists in the service class and return its default value for the service.

Example:

    <?php
    namespace App;
    use App\ServiceTagged;
    class Service implement ServiceTagged
    {
        public static function getDefaultPriority(): int
        {
            return 50; //This will be the default priority if it's not defined in a configuration file
        }
    }
    ?>
Copy link
Member

@yceruto yceruto left a comment

Choose a reason for hiding this comment

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

Hola! Congratulations for your first attempt :) 🎉

pcabreus added 4 commits June 9, 2019 23:02
It looks like `YamlFileLoader` makes `index_by` mandatory when you define the tagged service using `arguments: [!tagged { tag: 'app.handler'}]` syntax. It's needed to accept others parameters like the new `default_priority_method` without specify `index_by` and the `XmlFielLoader` seems to accept it.
Copy link
Member

@yceruto yceruto left a comment

Choose a reason for hiding this comment

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

Others code standard that aren't cover by fabbot.io:

pcabreus and others added 5 commits June 11, 2019 10:10
pcabreus added a commit to pcabreus/symfony-docs that referenced this pull request Jun 20, 2019
This documents symfony/symfony#31943 about adding a custom method to define the priority of services
@nicolas-grekas nicolas-grekas changed the title Define default priority inside service class [DependencyInjection] Define default priority inside service class Sep 3, 2020
Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

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

Thanks and sorry for the late review.
Here are some comments. Please rebase also.
Looks good to me otherwise.

@@ -118,27 +118,27 @@ function iterator(array $values): IteratorArgument
*
* @deprecated since Symfony 4.4, to be removed in 5.0, use "tagged_iterator" instead.
*/
function tagged(string $tag, string $indexAttribute = null, string $defaultIndexMethod = null): TaggedIteratorArgument
function tagged(string $tag, string $indexAttribute = null, string $defaultIndexMethod = null, bool $needsIndexes = false, string $defaultPriorityMethod = null): TaggedIteratorArgument
Copy link
Member

Choose a reason for hiding this comment

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

should be reverted, this function is deprecated, no need to alter it

}

/**
* Creates a lazy iterator by tag name.
*/
function tagged_iterator(string $tag, string $indexAttribute = null, string $defaultIndexMethod = null): TaggedIteratorArgument
function tagged_iterator(string $tag, string $indexAttribute = null, string $defaultIndexMethod = null, bool $needsIndexes = false, string $defaultPriorityMethod = null): TaggedIteratorArgument
Copy link
Member

Choose a reason for hiding this comment

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

$needsIndexes should be removed, it's always false for iterators

}

/**
* Creates a service locator by tag name.
*/
function tagged_locator(string $tag, string $indexAttribute, string $defaultIndexMethod = null): ServiceLocatorArgument
function tagged_locator(string $tag, string $indexAttribute, string $defaultIndexMethod = null, bool $needsIndexes = true, string $defaultPriorityMethod = null): ServiceLocatorArgument
Copy link
Member

Choose a reason for hiding this comment

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

$needsIndexes should be removed, it's always true for locators

$priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0;
$class = $container->getDefinition($serviceId)->getClass();
$class = $container->getParameterBag()->resolveValue($class) ?: null;
$reflectionClass = $container->getReflectionClass($class);
Copy link
Member

Choose a reason for hiding this comment

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

this line must be executed only if null !== $defaultPriorityMethod and $attributes[0]['priority'] is not set, so that we don't autoload a class for nothing when not needed

throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $serviceId));
}

$class = $r->name;
$class = $reflectionClass->name;
Copy link
Member

Choose a reason for hiding this comment

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

let's keep $r as the name here, that will reduce the diff, thus reduce future merge conflicts

@nicolas-grekas
Copy link
Member

Wait, this has already been implemented in #33628!
Thanks for pushing this forward and sorry for the confusion.

@nicolas-grekas nicolas-grekas removed this from the next milestone Oct 5, 2020
@nicolas-grekas nicolas-grekas added this to the 5.2 milestone Oct 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants