Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upChange providers strategy #143
Conversation
| @@ -8,16 +8,6 @@ | |||
|
|
|||
| abstract class AbstractContainerConfigurator | |||
This comment has been minimized.
This comment has been minimized.
samdark
Sep 3, 2020
Member
Seems it's near to empty now or at least name doesn't reflect the purpose anyway.
| @@ -267,7 +277,8 @@ private function addProvider($providerDefinition): void | |||
| */ | |||
| private function buildProvider($providerDefinition): ServiceProviderInterface | |||
| { | |||
| $provider = Normalizer::normalize($providerDefinition)->resolve($this); | |||
|
|
|||
| $provider = $this->factory->create($providerDefinition); | |||
This comment has been minimized.
This comment has been minimized.
samdark
Sep 3, 2020
Member
Why do we need to create an object right away? Can't we set the config as is?
This comment has been minimized.
This comment has been minimized.
yiiliveext
Sep 4, 2020
Author
Contributor
Why do we need to create an object right away? Can't we set the config as is?
We need to set params in the provider constructor.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
samdark
Sep 4, 2020
Member
Discussed in private. Decided that @yiiliveext will adjust it so providers array is returning instances instead of definitions.
| throw new InvalidConfigException( | ||
| 'Service provider should be an instance of ' . ServiceProviderInterface::class | ||
| ); | ||
| } | ||
|
|
||
| if ($provider instanceof DeferredServiceProviderInterface) { |
This comment has been minimized.
This comment has been minimized.
BoShurik
Sep 8, 2020
•
Does DeferredServiceProviderInterface make sense? Looks like all providers are lazy now
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
yiiliveext
Sep 9, 2020
Author
Contributor
DeferredProvider is for a heavyweight service initialization. For example, we should make a heavyweight API call and pass the received data to the service constructor. If we use this service only on a few routes, then why do we make the API call on each route? So, we use deferred providers to avoid this.
This comment has been minimized.
This comment has been minimized.
BoShurik
Sep 9, 2020
return [
HeavyService::class => static function (ContainerInterface $container) {
$data = $container->get(Api::class)->heavyCall();
return new HeavyService($data);
},
];Isn't this service will be initialized only when requested?
This comment has been minimized.
This comment has been minimized.
yiiliveext
Sep 9, 2020
Author
Contributor
Isn't this service will be initialized only when requested?
Yes, this is another way, it is appropriate in a simple case, but we may have something like that
class Provider implements ServiceProviderInterface
{
public function getDefinitions(): array
{
$rawData = file_get_contents('http:\\mysyte.com\something');
$dataForFirstService = $this->calculateDataForFirstService($rawData);
$dataForSecondService = $this->calculateDataForSecondService($rawData);
$dataForThirdService = $this->calculateDataForThirdService($rawData);
return [
FirstService::class => [
'__construct()' => [$dataForFirstService],
],
SecondService::class => [
'__construct()' => [$dataForSecondService],
],
ThirdService::class => [
'__construct()' => [$dataForThirdService],
],
];
}
public function calculateDataForFirstService($data)
{
//calculation
}
public function calculateDataForSecondService($data)
{
//calculation
}
public function calculateDataForThirdService($data)
{
//calculation
}
}
This comment has been minimized.
This comment has been minimized.
BoShurik
Sep 9, 2020
@yiiliveext make sense, but can be defined with factories:
return [
Api::class => [],
ApiInterface::class => static function (ContainerInterface $container) {
// To cache requests
return new CachedApiDecorator($container->get(Api::class));
},
ServiceFactory::class => [
// Also request may be cached in factory
'__construct' => [Reference::to(ApiInterface::class)],
],
FirstService::class => static function (ContainerInterface $container) {
return $container->get(ServiceFactory::class)->createFirst();
},
SecondService::class => static function (ContainerInterface $container) {
return $container->get(ServiceFactory::class)->createSecond();
},
ThirdService::class => static function (ContainerInterface $container) {
return $container->get(ServiceFactory::class)->createThird();
},
];Anyway, in advanced cases you probably need additional data from container to access API (tokens, request signer etc)
This comment has been minimized.
This comment has been minimized.
yiiliveext
Sep 9, 2020
Author
Contributor
Anyway, in advanced cases you probably need additional data from container to access
API(tokens, request signer etc)
Yes, I think it would be fine to add setContainer() method to DeferredProviderInterface.
|
Attention If use deffered providers, providers that do something other than the container configuration will stop working. Suggestion Add support For example, config: return [
'yiisoft/csrf' => static function() {
CsrfToken::initialize();
return [];
},
]; |
| * | ||
| * @throws InvalidConfigException | ||
| * @throws NotInstantiableException | ||
| * @see ServiceProviderInterface | ||
| * @see DeferredServiceProviderInterface | ||
| */ | ||
| private function addProvider($providerDefinition): void | ||
| private function addProvider($provider): void |
This comment has been minimized.
This comment has been minimized.
viktorprogger
Sep 9, 2020
| private function addProvider($provider): void | |
| private function addProvider(ServiceProviderInterface $provider): void |
|
yiiliveext commentedSep 1, 2020