Skip to content
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

[5.4] Add support for binding methods to the container #16800

Merged
merged 3 commits into from
Dec 14, 2016
Merged

[5.4] Add support for binding methods to the container #16800

merged 3 commits into from
Dec 14, 2016

Conversation

adamwathan
Copy link
Contributor

@adamwathan adamwathan commented Dec 14, 2016

Adds support for manually controlling how a method should be called when invoked with Container::call:

$this->app->bindMethod('App\Jobs\SomeJob@handle', function ($job, $app) {
    return $job->handle('foo', 'bar');
});

Prior to this, it was impossible to have parameters in the handle method of a job that could not be auto-resolved by the container, because there was no way to manually control what the parameters should be.

This means you are forced to use type hints for object parameters and have no ability to use primitives as parameters, or have to use the old undocumented job syntax where dependencies were passed to the constructor instead of to the handle method.

For example, it is currently impossible to write a job class like this, where the handle method has dependencies that can't be autoresolved:

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;

class AddCollaboratorToGitHubRepoJob implements ShouldQueue
{
    use Queueable;

    private $user;

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

    public function handle($githubOwner, $githubRepo, $githubToken)
    {
        (new Client)->put($this->collaboratorUrl($githubOwner, $githubRepo), [
            'headers' => ['Authorization' => "token {$githubToken}"],
            'json' => ['permission' => 'pull']
        ]);
    }

    private function collaboratorUrl($owner, repo)
    {
        return "https://api.github.com/repos/{$owner}/{$repo}/collaborators/{$this->user->github_username}";
    }
}

Using the functionality added in this PR, you could specify how handle should be called:

$this->app->bindMethod('App\Jobs\AddCollaboratorToGitHubRepoJob@handle', function ($job, $app) {
    return $job->handle(
        config('services.github.owner'),
        config('services.github.repo'),
        config('services.github.token')
    );
});

This PR intentionally adds only the minimal functionality needed to subvert this issue, and doesn't make any effort to support the when->needs->give syntax, or passing key => value parameters to optionally override things or any of those fancy more complex features.

Instead, it simply adds support for defining what should happen as a whole, much like you would with a standard container binding:

$this->app->singleton(PaymentGateway::class, function () {
    return new PaymentGateway(config('services.stripe.secret'));
});

Additional functionality like that could be added down the road, or we could simply roll with this forever, because it at least does what's needed to fix what's currently impossible.

@taylorotwell taylorotwell merged commit a153c59 into laravel:master Dec 14, 2016
@GrahamCampbell GrahamCampbell changed the title Add support for binding methods to the container [5.4] Add support for binding methods to the container Dec 15, 2016
@tillkruss
Copy link
Contributor

Neat!

@vnaki
Copy link

vnaki commented May 3, 2018

Greate!

@michael-rubel
Copy link
Contributor

If someone's interested in the feature, I've created a package that let us use method bindings with ease:
https://github.com/michael-rubel/laravel-enhanced-container

I also plan to extend the package functionality in the future.

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.

5 participants