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

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

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

  [ home ](https://msaied.com)    [ articles ](https://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%2Fmsaied.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%2Fmsaied.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://msaied.com/articles) 

 [ ![Eloquent Custom Casts: Encapsulating Value Objects Without the Bloat](https://cdn.msaied.com/174/2c75896ee4182bb2f66e2c93bed18796.png) laravel eloquent ddd 

### Eloquent Custom Casts: Encapsulating Value Objects Without the Bloat

Custom Eloquent casts let you bind rich value objects directly to model attributes. This article shows how to...

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

 14 Jun 2026     1 min read  

  Read    

 ](https://msaied.com/articles/eloquent-custom-casts-encapsulating-value-objects-without-the-bloat) [ ![Filament v4 Schema-Based Forms: Unified Schema API in Practice](https://cdn.msaied.com/173/6e0d9faa9137cb296e37831c3645e7ba.png) filament laravel filament-v4 

### Filament v4 Schema-Based Forms: Unified Schema API in Practice

Filament v4 replaces scattered form/infolist definitions with a single Schema API. This post walks through rea...

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

 14 Jun 2026     3 min read  

  Read    

 ](https://msaied.com/articles/filament-v4-schema-based-forms-unified-schema-api-in-practice) [ ![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://msaied.com/articles/the-pipeline-pattern-in-laravel-building-custom-pipelines-beyond-middleware) 

   [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://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://msaied.com)
- [Projects](https://msaied.com/projects)
- [Articles](https://msaied.com/articles)
- [Certificates](https://msaied.com/certificates)
- [Contact](https://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)
