laravel / ideas

Issues board used for Laravel internals discussions.
938 stars 28 forks source link

[IoC][Tag] Tag and keyBy services with method tag() to the Container #2519

Open camiloiglesias96 opened 3 years ago

camiloiglesias96 commented 3 years ago

Hi everybody,

I have 1 week going through laravel container methods in the code and some internet forums about the framework and at least in symfony it is possible to tag services with a specific key and then you can get this service with this key.

Actually you can do this

<?php

...

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->bind(ServiceInterface::class, Service::class);

        $this->app->tag([ServiceInterface::class], ['service.system']);
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
}

And then you can obtain this service with the app() helper and the tagged() method like this:

...

$services = iterator_to_array(app()->tagged('service.system'));

Output:
array => [
     0   => App\Services\Service {#361}
]
...

But sometimes we want assign a key without make intermediate transform process to the obtained iterator / array to then implement a service resolver class to get a specific or directly get direct access to array value obtaining the service instance like this:

#ServiceProvider
/**
 * Register any application services.
 *
 * @return void
 */
public function register()
{
     $this->app->bind(ServiceInterface::class, Service::class);

     $this->app->tag(['the_service' => ServiceInterface::class], ['service.system']);
}
...

#Accesing to value
$services = iterator_to_array(app()->tagged('service.system'));

Output:
array => [
     'the_service'   => App\Services\Service {#361}
]

#Getting service instance
$services['the_service']->calculate();

#Service class resolver

$resolver = new ServiceResolver($services);
$theService = $resolver->getInstance('the_service');
$result = $theService->calculate();
...

If wrong my explanation please support me Thank you