> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Service container

> Learn how Laravel's service container performs dependency injection and the basics of container bindings.

## What is the service container

Laravel's service container is a mechanism for managing class dependencies and performing dependency injection. Dependency injection means the dependencies a class needs are "injected" into the class via the constructor, or in some cases, setter methods.

Look at the following example.

```php theme={null}
<?php

namespace App\Http\Controllers;

use App\Services\AppleMusic;
use Illuminate\View\View;

class PodcastController extends Controller
{
    /**
     * Create a new controller instance.
     */
    public function __construct(
        protected AppleMusic $apple,
    ) {}

    /**
     * Show information about the given podcast.
     */
    public function show(string $id): View
    {
        return view('podcasts.show', [
            'podcast' => $this->apple->findPodcast($id)
        ]);
    }
}
```

In this example, the `PodcastController` needs to fetch podcasts from a data source like Apple Music. So we **inject** a service that can fetch podcasts. By injecting the service, we can easily swap in a mock (dummy implementation) of the `AppleMusic` service during testing.

<Info>
  A deep understanding of the service container is essential for building a large Laravel application. It also helps you contribute to the Laravel core itself.
</Info>

```mermaid theme={null}
flowchart TD
    A["Service provider<br>register()"] --> B["Service container<br>Register binding"]
    B --> C{"Resolution request<br>make() / auto-inject"}
    C -- "Concrete class" --> D["Auto-resolve<br>via reflection"]
    C -- "Interface" --> E["Resolve the registered<br>implementation class"]
    D --> F["Instantiate and<br>inject into constructor"]
    E --> F
```

## Zero-configuration resolution

If a class has no dependencies or only depends on other concrete classes (not interfaces), the container does not need to be instructed on how to resolve that class. For example, you may place the following code in your `routes/web.php` file:

```php theme={null}
<?php

class Service
{
    // ...
}

Route::get('/', function (Service $service) {
    dd($service::class);
});
```

<Info>
  This example defines a class inside the route file for demonstration purposes. In a real application, service classes should be defined in the `app/Services` directory.
</Info>

When you visit this route, Laravel automatically resolves the `Service` class and injects it into the route's handler. You get the benefits of dependency injection without needing any configuration files.

Many classes you write in a Laravel application—controllers, event listeners, middleware, and so on—automatically have their dependencies injected via the container.

## Binding

### Basic binding

Almost all of your bindings will be registered inside [service providers](/en/service-providers). Inside a service provider, you have access to the container via the `$this->app` property.

#### bind

Use the `bind` method to register a binding, passing the class or interface name that we wish to register along with a closure.

```php theme={null}
use App\Services\Transistor;
use App\Services\PodcastParser;
use Illuminate\Contracts\Foundation\Application;

$this->app->bind(Transistor::class, function (Application $app) {
    return new Transistor($app->make(PodcastParser::class));
});
```

The closure receives the container itself as an argument. You can use this to resolve sub-dependencies.

To manipulate the container outside a service provider, use the `App` facade.

```php theme={null}
use App\Services\Transistor;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\Facades\App;

App::bind(Transistor::class, function (Application $app) {
    // ...
});
```

<Info>
  There is no need to bind classes into the container if they do not depend on any interfaces. The container can resolve these objects automatically using reflection.
</Info>

#### singleton

The `singleton` method binds a class or interface such that it is only resolved once. Once a singleton has been resolved, the same instance is returned on subsequent calls into the container.

```php theme={null}
use App\Services\Transistor;
use App\Services\PodcastParser;
use Illuminate\Contracts\Foundation\Application;

$this->app->singleton(Transistor::class, function (Application $app) {
    return new Transistor($app->make(PodcastParser::class));
});
```

You may use the `singletonIf` method to register a singleton container binding only if a binding has not already been registered for the given type.

```php theme={null}
$this->app->singletonIf(Transistor::class, function (Application $app) {
    return new Transistor($app->make(PodcastParser::class));
});
```

#### Singleton attribute

Alternatively, you may mark an interface or class with the `#[Singleton]` attribute to indicate to the container that it should be resolved one time.

```php theme={null}
<?php

namespace App\Services;

use Illuminate\Container\Attributes\Singleton;

#[Singleton]
class Transistor
{
    // ...
}
```

#### Binding scoped singletons

The `scoped` method binds a class or interface into the container that should only be resolved one time within a given Laravel request / job lifecycle. While this method is similar to the `singleton` method, instances registered using the `scoped` method are flushed whenever the Laravel application starts a new "lifecycle", such as when a [Laravel Octane](/en/octane) worker processes a new request or when a [queue worker](/en/queues) processes a new job.

```php theme={null}
use App\Services\Transistor;
use App\Services\PodcastParser;
use Illuminate\Contracts\Foundation\Application;

$this->app->scoped(Transistor::class, function (Application $app) {
    return new Transistor($app->make(PodcastParser::class));
});
```

You may use the `scopedIf` method to register a scoped container binding only if a binding has not already been registered for the given type.

```php theme={null}
$this->app->scopedIf(Transistor::class, function (Application $app) {
    return new Transistor($app->make(PodcastParser::class));
});
```

#### Scoped attribute

Alternatively, you may mark an interface or class with the `#[Scoped]` attribute to indicate to the container that it should be resolved one time within a given Laravel request / job lifecycle.

```php theme={null}
<?php

namespace App\Services;

use Illuminate\Container\Attributes\Scoped;

#[Scoped]
class Transistor
{
    // ...
}
```

#### instance

You may also bind an existing object instance into the container using the `instance` method. The given instance will always be returned on subsequent calls into the container.

```php theme={null}
use App\Services\Transistor;
use App\Services\PodcastParser;

$service = new Transistor(new PodcastParser);

$this->app->instance(Transistor::class, $service);
```

### Binding interfaces to implementations

One of the powerful features of the service container is its ability to bind an interface to a given implementation. For example, suppose we have an `EventPusher` interface and a `RedisEventPusher` implementation.

```php theme={null}
use App\Contracts\EventPusher;
use App\Services\RedisEventPusher;

$this->app->bind(EventPusher::class, RedisEventPusher::class);
```

This tells the container that it should inject the `RedisEventPusher` when a class needs an implementation of `EventPusher`. Then, all you need to do is type-hint the `EventPusher` interface in a constructor.

```php theme={null}
use App\Contracts\EventPusher;

/**
 * Create a new class instance.
 */
public function __construct(
    protected EventPusher $pusher,
) {}
```

<Tip>
  By depending on an interface, you don't need to change your code even if you swap out the implementation. This makes testing and future changes easier.
</Tip>

#### Bind attribute

Laravel also provides a `Bind` attribute for added convenience. You can apply this attribute to any interface to tell Laravel which implementation should be automatically injected whenever that interface is requested. When using the `Bind` attribute, there is no need to perform any additional service registration in your application's service providers.

In addition, multiple `Bind` attributes may be placed on an interface in order to configure a different implementation that should be injected for a given set of environments.

```php theme={null}
<?php

namespace App\Contracts;

use App\Services\FakeEventPusher;
use App\Services\RedisEventPusher;
use Illuminate\Container\Attributes\Bind;

#[Bind(RedisEventPusher::class)]
#[Bind(FakeEventPusher::class, environments: ['local', 'testing'])]
interface EventPusher
{
    // ...
}
```

Furthermore, [Singleton](#singleton-attribute) and [Scoped](#scoped-attribute) attributes may be applied to indicate if the container bindings should be resolved once or once per request / job lifecycle.

```php theme={null}
use App\Services\RedisEventPusher;
use Illuminate\Container\Attributes\Bind;
use Illuminate\Container\Attributes\Singleton;

#[Bind(RedisEventPusher::class)]
#[Singleton]
interface EventPusher
{
    // ...
}
```

## Automatic resolution (DI via type hints)

When resolving classes such as controllers, event listeners, and middleware, the service container examines the constructor's type hints and injects the dependencies automatically.

```php theme={null}
<?php

namespace App\Http\Controllers;

use App\Repositories\UserRepository;

class UserController extends Controller
{
    /**
     * Create a new controller instance.
     */
    public function __construct(
        protected UserRepository $users,
    ) {}
}
```

If `UserRepository` doesn't depend on an interface, you don't need to register it in the container. Just visit the following route and the container automatically resolves and injects the dependency into the controller.

## Resolving from the container

### The make method

Use the `make` method to resolve a class instance from the container.

```php theme={null}
use App\Services\Transistor;

$transistor = app()->make(Transistor::class);
```

If some of your class's dependencies are not resolvable by the container, you can inject additional arguments using the `makeWith` method.

```php theme={null}
$transistor = $this->app->makeWith(Transistor::class, ['id' => 1]);
```

### Automatic injection

In practice, you'll rarely need to call the `make` method directly. Just add type hints to the constructor of a class that the container resolves (controllers, event listeners, middleware, and so on) and the container will inject them automatically.

## Facades and the container

Laravel facades provide a static interface to objects in the container. For example, `Cache::get()` internally retrieves the `Cache` service from the container and calls the method.

```php theme={null}
use Illuminate\Support\Facades\Cache;

// Using the facade
Cache::get('key');

// Equivalent call using the container directly
app('cache')->get('key');
```

Facades are a convenient wrapper around the container. You can also swap facades with mocks during testing.

```php theme={null}
use Illuminate\Support\Facades\Cache;

Cache::shouldReceive('get')
    ->once()
    ->with('key')
    ->andReturn('value');
```

## Practical example of constructor injection

Let's look at a typical pattern in a real application.

<Steps>
  <Step title="Define the interface">
    ```php theme={null}
    <?php

    namespace App\Contracts;

    interface PaymentGateway
    {
        public function charge(int $amount, string $token): bool;
    }
    ```
  </Step>

  <Step title="Create the implementation class">
    ```php theme={null}
    <?php

    namespace App\Services;

    use App\Contracts\PaymentGateway;

    class StripePaymentGateway implements PaymentGateway
    {
        public function charge(int $amount, string $token): bool
        {
            // Payment processing using the Stripe API...
            return true;
        }
    }
    ```
  </Step>

  <Step title="Bind it in a service provider">
    ```php theme={null}
    use App\Contracts\PaymentGateway;
    use App\Services\StripePaymentGateway;

    $this->app->singleton(PaymentGateway::class, StripePaymentGateway::class);
    ```
  </Step>

  <Step title="Receive it via injection in a controller">
    ```php theme={null}
    <?php

    namespace App\Http\Controllers;

    use App\Contracts\PaymentGateway;
    use Illuminate\Http\Request;

    class OrderController extends Controller
    {
        public function __construct(
            protected PaymentGateway $payment,
        ) {}

        public function store(Request $request)
        {
            $this->payment->charge(
                $request->amount,
                $request->payment_token
            );

            // ...
        }
    }
    ```
  </Step>
</Steps>

With this pattern, switching the payment service from Stripe to another provider only requires changing the binding in one place.

## Next steps

<Card title="Service providers" icon="plug" href="/en/service-providers">
  Learn how to register bindings using service providers.
</Card>


## Related topics

- [Service providers](/en/service-providers.md)
- [Request lifecycle](/en/lifecycle.md)
- [Application Structure in Laravel 11 and Later](/en/advanced/app-structure.md)
- [Laravel Package Development](/en/advanced/package-development.md)
- [Mocking](/en/mocking.md)
