Skip to content

Conversation

@lorisleiva
Copy link
Contributor

Description

As mentioned in #35202, this PR enables us to hook some custom logic into the beginning of the container resolution — i.e. before an instance as been resolved from the provided abstract.

Usage

It uses the same conventions as the $(after)ResolvingCallbacks and $global(After)ResolvingCallbacks to register and trigger the callbacks.

// Adds a specific before resolving callback.
$this->app->beforeResolving(MyService::class, function ($abstract, $parameters, $app) {
    // ...
});

// Adds a global before resolving callback.
$this->app->beforeResolving(function ($abstract, $parameters, $app) {
    // ...
});

Advanced usage

These before resolving callbacks can be used as a way to dynamically add specific extenders and, therefore, remove the need for #35202.

For example, this global extender...

$this->app->extend(function ($instance, $app) {
    if (! $app->isProduction() && $instance instanceof CanBeFaked) {
        return FakeServiceDecorator($instance);
    }

    return $instance;
});

... could be achieve with the following before resolving callback:

$this->app->beforeResolving(function ($abstract, $parameters, $app) {
    if ($app->isProduction() || ! is_subclass_of($abstract, CanBeFaked::class) || $app->resolved($abstract)) {
        return;
    }

    $app->extend($abstract, function ($instance) {
        return FakeServiceDecorator($instance);
    });
});

Since the specific before resolving callbacks already check for inheritance, this could be refactored to:

$this->app->beforeResolving(CanBeFaked::class, function ($abstract, $parameters, $app) {
    if ($app->isProduction() || $app->resolved($abstract)) {
        return;
    }

    $app->extend($abstract, function ($instance) {
        return FakeServiceDecorator($instance);
    });
});

Note the use of $app->resolved($abstract), to ensure we do not add the same extender multiple times.

Backward compatibility

This PR does not add any breaking changes.

It triggers new types of callbacks that wouldn't have been registered before.

@lorisleiva lorisleiva changed the title Add before resolving callbacks [8.x] Add before resolving callbacks Nov 15, 2020
@taylorotwell taylorotwell merged commit 6e9cd67 into laravel:8.x Nov 16, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants