Laravel Service Container: Contextual Binding &amp; Injection | Mohamed Said        [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://www.msaied.com) [ Home ](https://www.msaied.com) [ Projects ](https://www.msaied.com/projects) [ Articles  ](https://www.msaied.com/articles) [ Certificates ](https://www.msaied.com/certificates) [ Contact ](https://www.msaied.com#contact-section) 

       [  ](https://github.com/EG-Mohamed)       

 [ Home ](https://www.msaied.com) [ Projects ](https://www.msaied.com/projects) [ Articles ](https://www.msaied.com/articles) [ Certificates ](https://www.msaied.com/certificates) [ Contact ](https://www.msaied.com#contact-section) 

  [ home ](https://www.msaied.com)    [ articles ](https://www.msaied.com/articles)    Contextual Binding and Method Injection in Laravel's Service Container        On this page       1. [  Beyond app()-&gt;make(): The Container Features Most Teams Ignore ](#beyond-codeapp-gtmakecode-the-container-features-most-teams-ignore)
2. [  Contextual Binding ](#contextual-binding)
3. [  Tagging Services ](#tagging-services)
4. [  Method Injection ](#method-injection)
5. [  Practical Pattern: Pipeline Stage Injection ](#practical-pattern-pipeline-stage-injection)
6. [  Takeaways ](#takeaways)

  ![Contextual Binding and Method Injection in Laravel's Service Container](https://cdn.msaied.com/170/396bdacb111411b734f3018920214c20.png)

  #laravel   #service-container   #dependency-injection   #architecture  

 Contextual Binding and Method Injection in Laravel's Service Container 
========================================================================

     14 Jun 2026      3 min read    ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said  

       Table of contents

1. [  01   Beyond app()-&gt;make(): The Container Features Most Teams Ignore  ](#beyond-codeapp-gtmakecode-the-container-features-most-teams-ignore)
2. [  02   Contextual Binding  ](#contextual-binding)
3. [  03   Tagging Services  ](#tagging-services)
4. [  04   Method Injection  ](#method-injection)
5. [  05   Practical Pattern: Pipeline Stage Injection  ](#practical-pattern-pipeline-stage-injection)
6. [  06   Takeaways  ](#takeaways)

 Beyond `app()->make()`: The Container Features Most Teams Ignore
----------------------------------------------------------------

Every Laravel developer knows `bind` and `singleton`. Fewer reach for contextual binding, tagging, or method injection — features that eliminate a surprising amount of conditional wiring code.

### Contextual Binding

Contextual binding answers the question: *"What should the container resolve when class A asks for interface X, versus when class B asks for the same interface?"*

```php
// AppServiceProvider::register()
$this->app
    ->when(ReportExporter::class)
    ->needs(FilesystemInterface::class)
    ->give(fn () => Storage::disk('s3'));

$this->app
    ->when(LocalPreviewGenerator::class)
    ->needs(FilesystemInterface::class)
    ->give(fn () => Storage::disk('local'));

```

Both classes declare `__construct(FilesystemInterface $fs)`. The container resolves the correct disk without either class knowing about the other or about config flags. No `if (app()->environment(...))` inside a constructor.

You can also bind a primitive this way:

```php
$this->app
    ->when(StripeWebhookProcessor::class)
    ->needs('$secret')
    ->give(config('services.stripe.webhook_secret'));

```

This keeps secrets out of the class body while remaining fully testable — swap the binding in a test service provider and the constructor still receives a plain string.

### Tagging Services

Tagging lets you resolve a *group* of implementations at once. This is the clean alternative to a hand-rolled registry array.

```php
// Register
$this->app->bind(SlackNotifier::class);
$this->app->bind(EmailNotifier::class);
$this->app->bind(PushNotifier::class);

$this->app->tag(
    [SlackNotifier::class, EmailNotifier::class, PushNotifier::class],
    'notifiers'
);

```

```php
// Consume
class BroadcastAlert
{
    /** @param iterable $notifiers */
    public function __construct(
        private readonly iterable $notifiers
    ) {}

    public function send(Alert $alert): void
    {
        foreach ($this->notifiers as $notifier) {
            $notifier->notify($alert);
        }
    }
}

```

```php
// Wire it
$this->app->bind(BroadcastAlert::class, function ($app) {
    return new BroadcastAlert($app->tagged('notifiers'));
});

```

`$app->tagged('notifiers')` returns a lazy generator — implementations are only instantiated when iterated. Adding a new notifier is a one-line tag registration; `BroadcastAlert` never changes.

### Method Injection

The container can resolve dependencies for *any* callable, not just constructors. `app()->call()` accepts a class-method pair, a closure, or an invokable:

```php
class ReportController
{
    public function generate(
        Request $request,
        ReportBuilder $builder,  // resolved by container
        PdfRenderer $renderer    // resolved by container
    ): Response {
        $report = $builder->build($request->validated());
        return response($renderer->render($report));
    }
}

// In a test or CLI command:
$response = app()->call(
    [app(ReportController::class), 'generate'],
    ['request' => $fakeRequest]
);

```

This is how Laravel resolves route controller methods internally. You can use the same mechanism in console commands, event listeners, or pipeline stages without pulling the container into the class itself.

### Practical Pattern: Pipeline Stage Injection

```php
class EnrichOrderData
{
    public function handle(
        Order $order,
        Closure $next,
        TaxCalculator $tax,   // injected by app()->call()
        FraudScorer $fraud
    ): Order {
        $order->tax_amount = $tax->calculate($order);
        $order->fraud_score = $fraud->score($order);
        return $next($order);
    }
}

```

When you drive the pipeline with `app()->call([$stage, 'handle'], $payload)`, each stage gets its own dependencies resolved fresh — no constructor pollution, no service locator.

### Takeaways

- **Contextual binding** removes environment checks and config reads from constructors, keeping classes ignorant of their deployment context.
- **Tagging** replaces hand-rolled registries with a lazy, extensible collection resolved by the container.
- **Method injection via `app()->call()`** is not just a framework internal — use it in pipelines, commands, and test helpers to keep classes lean.
- All three features are fully compatible with constructor injection; they compose rather than replace it.
- Prefer registering contextual bindings in a dedicated `ContextualBindingServiceProvider` to keep `AppServiceProvider` readable.

 Found this useful?

          [  ](https://twitter.com/intent/tweet?url=https%3A%2F%2Fwww.msaied.com%2Farticles%2Fcontextual-binding-and-method-injection-in-laravels-service-container&text=Contextual+Binding+and+Method+Injection+in+Laravel%27s+Service+Container) [  ](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fwww.msaied.com%2Farticles%2Fcontextual-binding-and-method-injection-in-laravels-service-container) 

 Frequently Asked Questions 
----------------------------

  3 questions  

     Q01  Does contextual binding work with interfaces resolved via constructor injection automatically?        Yes. When the container autowires a constructor it checks contextual bindings first. If the consuming class has a contextual rule for the requested type, that rule wins over any global binding. 

      Q02  Is `app()-&gt;tagged()` eager or lazy?        It returns a generator, so tagged implementations are instantiated only when you iterate over them. This means unused notifiers in a broadcast scenario cost nothing. 

      Q03  Can I use method injection in Artisan commands?        Yes. Override `handle()` with any type-hinted dependencies beyond the default Command signatures and Laravel will resolve them via the container automatically, the same way it does for controller methods. 

  Continue reading

 More Articles 
---------------

 [ View all    ](https://www.msaied.com/articles) 

 [ ![The Pipeline Pattern in Laravel: Building Custom Pipelines Beyond Middleware](https://cdn.msaied.com/172/a5dea5e84a6eab22d5d7a76869aaecb4.png) laravel design-patterns pipeline 

### The Pipeline Pattern in Laravel: Building Custom Pipelines Beyond Middleware

Laravel's Pipeline class is far more than the engine behind HTTP middleware. Learn how to compose reusable, te...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 14 Jun 2026     3 min read  

  Read    

 ](https://www.msaied.com/articles/the-pipeline-pattern-in-laravel-building-custom-pipelines-beyond-middleware) [ ![Read/Write Splitting, Connection Pooling, and Sticky Reads in Laravel](https://cdn.msaied.com/171/92ea6daa5c8b599f43ef1c69a7c1eaa6.png) laravel database performance 

### Read/Write Splitting, Connection Pooling, and Sticky Reads in Laravel

Learn how Laravel's database layer handles read/write splitting, when sticky reads save you from replication l...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 14 Jun 2026     4 min read  

  Read    

 ](https://www.msaied.com/articles/readwrite-splitting-connection-pooling-and-sticky-reads-in-laravel) [ ![PostgreSQL JSONB in Laravel: Indexing, Querying, and Casting Without the Chaos](https://cdn.msaied.com/169/5efebaf19646869da7c6064340c7d09f.png) laravel postgresql eloquent 

### PostgreSQL JSONB in Laravel: Indexing, Querying, and Casting Without the Chaos

JSONB columns are powerful but easy to misuse. Learn how to index, query, and cast PostgreSQL JSONB data in La...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 14 Jun 2026     3 min read  

  Read    

 ](https://www.msaied.com/articles/postgresql-jsonb-in-laravel-indexing-querying-and-casting-without-the-chaos) 

   [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://www.msaied.com)Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

Explore

- [Home](https://www.msaied.com)
- [Projects](https://www.msaied.com/projects)
- [Articles](https://www.msaied.com/articles)
- [Certificates](https://www.msaied.com/certificates)
- [Contact](https://www.msaied.com#contact-section)

Connect

- [   hello@msaied.com ](mailto:hello@msaied.com)
- [   +20 109 461 9204 ](tel:+201094619204)

© 2026 Mohamed Said. All rights reserved.

 [  ](https://github.com/EG-Mohamed) [  ](https://www.linkedin.com/in/msaiedm/) [  ](https://wa.me/201094619204) [  ](mailto:hello@msaied.com) [  ](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
