#I'm not able to instantiate a service provider from another service provider

26 messages · Page 1 of 1 (latest)

gloomy lynx
#
class MyServiceProvider extends ServiceProvider
{
    public $foo;

    public function __construct($app)
    {
        parent::__construct($app);

        if ($someCondition) {
            $this->foo = $app->make(OneServiceProvider::class);
        } else {
            $this->foo = $app->make(AnotherServiceProvider::class);
        }
    }

    public function register()
    {
        $this->app->singleton(self::class, function ($app) {
            return new static($app);
        });
    }
}

I'm getting an error:
Unresolvable dependency resolving [Parameter #0 [ <required> $app ]] in class App\xxx\AnotherServiceProvider

nimble inlet
#

What is the problem you’re actually trying to solve here?

gloomy lynx
#

i have two different services which i'm querying and i tried to wrap them into a single 'repository' like service provider and based on a specific logic i need to swap them.

nimble inlet
#

Can you show a concrete example of what you’re trying to do? What’s the condition?

gloomy lynx
#

i searching for an parameter in the http request and if exists i'm changing the provider

#

this is the condition

nimble inlet
#

Why on earth is a request parameter changing what is being bound to the service container?

gloomy lynx
#
$request             = AppRequest::createFromGlobals();
$isHybridModelActive = $request->get('hybrid_model', false);
#

as i mentioned i have two different service providers which are used to call 2 diferent API's which basically returns similar data

nimble inlet
#

I don’t think you understand what service providers are.

#

They register services in the service container. If you’re handling a request, then all service providers have already been registered and booted.

#

Create an interface that both of your repositories or whatever should implement.

nimble inlet
#

Bind the “default” implementation in your AppServiceProvider:

$this->app->singleton(SomeInterface::class, DefaultImplementation::class);

Then use middleware to override the binding if whatever request parameter is present:

class DoHybridStuff
{
    protected $container;

    public function __construct(Container $container)
    {
        $this->container = $container;
    }

    public function handle(Request $request, Closure $next)
    {
        if ($request->query('hybrid_model')) {
            $this->container->bind(SomeInterface::class, AlternativeImplementation::class);
        }

        return $next($request);
    }
}

You can now type-hint SomeInterface in your controller and you should get one of two implementations back depending on if the URL contains ?hybrid_model=1 or not.

#

Still seems an awful way of doing things, though.

#

I have no idea why a query string parameter would be changing what is getting registered in your application’s service container.

gloomy lynx
#

thanks for the idea i will give it a try, for sure

gloomy lynx
#

do you have a better idea of doing this?

nimble inlet
#

What’s the difference between the two third parties that I should be passing a query string parameter to pick which one gets queried?

gloomy lynx
#

our service is a categorisation model, we've just released a new version of the model and we need to test how well is it works through an AB testing in our apps and that AB testing group will pass an parameter to the backend which will decide which categorisation model to use

hollow imp
gloomy lynx