-
-
Notifications
You must be signed in to change notification settings - Fork 46
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
Willl be Service Locator later in package? #255
Comments
We recommend use DI instead of service locator. See Use DI instead of service locator. Also we planned make module container for configuration of modules. |
@vjik this is different purpose. I have some folder with 10 services those have same interface. Does DI allow to do this? Because I do not need any another services. May be by some tag like it do Symfony? I want pick each service from service locator to apply internal logic. |
You can configure in DI container each service separately:
And use concrete service in your classes: final class MyClass {
public __construct(Service1 $service) {}
}
DI support tags (see https://github.com/yiisoft/di#container-tags) |
I understand how to use DI =) But it lightly different:
Then my general service for example class PatternRecognizer
{
public function __copnstruct(StrategyLocator $sl)....
public function recognize(string $content)
{
foreach($this->sl->generateService() as $strategy){
$result = $strategy->applyTo(string $content);
...
}
return $result;
}
} Or another console command class: |
Try the following way: class StrategyResolver
{
public function __construct($strategy1, $strategy2, ...)
{
$this->strategies = [
's1' => $strategy1,
's2' => $strategy2,
];
}
public function getStrategy(string $alias)
{
return $this->strategies[$alias];
}
} But I suggest you to encapsulate your logic into "strategies": class StrategyResolver
{
public function __construct($strategy1, $strategy2, ...)
{
$this->strategies = [
$strategy1,
$strategy2,
];
}
public function do($context)
{
foreach($strategies as $strategy) {
if ($strategy->satisfied($context)) {
return $strategy->do($context)
}
}
throw new RuntimeException('No one strategy was satisfied to context');
}
} If you don't want to inject all services to work with only one you can make services lazy. I hope when we add "autotagged" services by interface like the Symfony does, you can make that resolver lighter: The resolver will be look like this: class StrategyResolver
{
public function __construct(StrategyInterface ...$strategies)
{
$this->strategies = $strategies
}
// ...
} And the Also you can add a tag to each service explicitly. Read the doc how to do it now. |
In the case, when I will detect matched strategy I should break resolution of strategies and return result, so in fact it can be enough to instantiate only few strategies. |
Yes. For majority of cases it's not a good idea. Leads to tight coupling so we'll avoid using/mentioning it. Your case is a bit special so it may make sense for you since you know what you want to do and why. |
I think it's a quite common use case. E.g. implementing command bus without service locator leads to inject whole container that leads to much more coupling |
Ability to disable autowiring in container probably will solve the issue |
If we touched autowiring, then: Disable autowiring of everything also can help to make some services private in scope of module. It is useful when vendors want to register only certain services or facades of their module and hide for internal usage some exclusive services. |
@BoShurik isn't that usually a factory? |
@andrew-svirin can't it be solved with composite containers? |
@samdark It can be solved with factory but if handler is stateless (it's usually is) we can get benefits when using RR and swoole |
I am not familiar with CompositeContainer. Do you have any reference with an example =) ? |
@samdark thanks ) I will try to use this sub container, but I am not sure that it can navigate through each registered service in it. Anyway if follow the rule "Principle_of_least_astonishment" then here much more fitting Service Locator =) |
@samdark |
@andrew-svirin yes, it could be implemented like that. Still, I don't think it should be part of the framework. |
Hi,
I have some module that have group of similar services and I want to manipulate with these services by ServiceLocator.
Just for information: Will you have ServiceLocator later or I can make it myself for my needs?
The text was updated successfully, but these errors were encountered: