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
Member

@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
2 checks passed
2 checks passed
continuous-integration/styleci/pr The StyleCI analysis has passed
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
@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

@tillkruss tillkruss commented Dec 17, 2016

Neat!

@Vnaki
Copy link

@Vnaki Vnaki commented May 3, 2018

Greate!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

4 participants