﻿# Dependency Injection

<!-- Version variant: core_7; default: [/nservicebus/dependency-injection/index.md](/nservicebus/dependency-injection/index.md) -->


NServiceBus automatically registers and invokes message handlers, sagas, and other user-provided extension points using a dependency injection container.

## Modes of operation

NServiceBus supports two modes for dependency injection:

- **Internally managed:** NServiceBus manages the container lifecycle as part of the endpoint lifecycle.
- **Externally managed:** The application or host provides and controls the container lifecycle.

## Internally managed mode

In *internally managed* mode, NServiceBus manages the entire lifecycle of the container, including registration, component resolution, and disposal.

### Built-in default container

NServiceBus has a built-in default container with an API for registration of user types. The following dependency lifecycles are supported:

#### Instance per call

A new instance will be returned for each call.

Represented by the enum value `DependencyLifecycle.InstancePerCall`.

<!-- snippet: InstancePerCall -->

```cs
endpointConfiguration.RegisterComponents(
    registration: configureComponents =>
    {
        configureComponents.ConfigureComponent<MyService>(DependencyLifecycle.InstancePerCall);
    });
```

<!-- endsnippet -->

or using a delegate:

<!-- snippet: DelegateInstancePerCall -->

```cs
endpointConfiguration.RegisterComponents(
    registration: configureComponents =>
    {
        configureComponents.ConfigureComponent(
            componentFactory: () =>
            {
                return new MyService();
            },
            dependencyLifecycle: DependencyLifecycle.InstancePerCall);
    });
```

<!-- endsnippet -->

#### Instance per unit of work

The instance will be a singleton for the duration of the [unit of work](/nservicebus/pipeline/unit-of-work.md). In practice this means the processing of a single transport message.

Represented by the enum value `DependencyLifecycle.InstancePerUnitOfWork`.

<!-- snippet: InstancePerUnitOfWork -->

```cs
endpointConfiguration.RegisterComponents(
    registration: configureComponents =>
    {
        configureComponents.ConfigureComponent<MyService>(DependencyLifecycle.InstancePerUnitOfWork);
    });
```

<!-- endsnippet -->

or using a delegate:

<!-- snippet: DelegateInstancePerUnitOfWork -->

```cs
endpointConfiguration.RegisterComponents(
    registration: configureComponents =>
    {
        configureComponents.ConfigureComponent(
            componentFactory: () =>
            {
                return new MyService();
            },
            dependencyLifecycle: DependencyLifecycle.InstancePerUnitOfWork);
    });
```

<!-- endsnippet -->

#### Single instance

The same instance will be returned each time.

Represented by the enum value `DependencyLifecycle.SingleInstance`.

> [!WARNING]
> `SingleInstance` components that have dependencies that are scoped `InstancePerCall` or `InstancePerUnitOfWork` will still resolve. In effect, these dependencies, while not scoped as `SingleInstance`, will behave as if they are `SingleInstance` because the instances will exist inside the parent component.

<!-- snippet: SingleInstance -->

```cs
endpointConfiguration.RegisterComponents(
    registration: configureComponents =>
    {
        configureComponents.ConfigureComponent<MyService>(DependencyLifecycle.SingleInstance);
    });
```

<!-- endsnippet -->

or using a delegate:

<!-- snippet: DelegateSingleInstance -->

```cs
endpointConfiguration.RegisterComponents(
    registration: configureComponents =>
    {
        configureComponents.ConfigureComponent(
            componentFactory: () =>
            {
                return new MyService();
            },
            dependencyLifecycle: DependencyLifecycle.SingleInstance);
    });
```

<!-- endsnippet -->

or using the explicit singleton API:

<!-- snippet: RegisterSingleton -->

```cs
endpointConfiguration.RegisterComponents(
    registration: configureComponents =>
    {
        configureComponents.RegisterSingleton(new MyService());
    });
```

<!-- endsnippet -->

### Using a third party container

NServiceBus also supports the following third party containers:

* [Autofac](autofac.md)
* [CastleWindsor](castlewindsor.md)
* [Ninject](ninject.md)
* [SimpleInjector](https://github.com/WilliamBZA/NServicebus.SimpleInjector) ([Community project](/nservicebus/community/index.md))
* [Spring](spring.md)
* [StructureMap](structuremap.md)
* [Unity](unity.md)

#### Plugging in other containers

If a specific library is not supported, create a plugin using the `IContainer` abstraction. Once this is created and registered, NServiceBus will use the custom dependency injection to look up its own dependencies.

Create a class that implements 'IContainer':

<!-- snippet: CustomContainer -->

```cs
public class MyContainer :
    IContainer
{
```

<!-- endsnippet -->

Create a class that implements 'ContainerDefinition' and returns the 'IContainer' implementation:

<!-- snippet: CustomContainerDefinition -->

```cs
public class MyContainerDefinition :
    ContainerDefinition
{
    public override IContainer CreateContainer(ReadOnlySettings settings)
    {
        return new MyContainer();
    }
}
```

<!-- endsnippet -->

Then register the `ContainerDefinition` to be used:

<!-- snippet: CustomContainerUsage -->

```cs
endpointConfiguration.UseContainer<MyContainerDefinition>();
```

<!-- endsnippet -->


## Externally managed mode

In *externally managed* mode, NServiceBus registers its components in the container but does not own the container's lifecycle. The container is provided by the user in two phases, one for registration (`IConfigureComponents`) and one for resolution (`IBuilder`).

> [!WARNING]
> Every NServiceBus endpoint requires its own dependency injection container. Sharing containers across multiple endpoints results in conflicting registrations and might cause incorrect behavior or runtime errors.

During the registration phase, an instance of `IConfigureComponents` is passed to the `EndpointWithExternallyManagedContainer.Create` method. For example, for Autofac's `ContainerBuilder`, this is the phase during which its type registration methods would be called.

<!-- snippet: ExternalPrepare -->

```cs
IConfigureComponents configureComponents =
    AdaptContainerForRegistrationPhase(myCustomContainer);

var startableEndpoint = EndpointWithExternallyManagedContainer.Create(endpointConfiguration, configureComponents);
```

<!-- endsnippet -->

Later, during the resolution phase, the `Start` method requires an instance of `IBuilder`. At this stage, the container has already been initialized with all its registrations. For example, for Autofac's `ContainerBuilder`, this is the phase during which its `Build` method would be called.

<!-- snippet: ExternalStart -->

```cs
IBuilder builder = AdaptContainerForResolutionPhase(myCustomContainer);

var startedEndpoint = await startableEndpoint.Start(builder);
```

<!-- endsnippet -->

> [!NOTE]
> The `Adapt` methods are implemented by the user and are container-specific. [NServiceBus.Extensions.DependencyInjection](/nservicebus/dependency-injection/extensions-dependencyinjection.md) supports externally managed mode using `Microsoft.Extensions.DependencyInjection` abstractions (`IServiceCollection` and `IServiceProvider`) that are supported by most dependency injection containers.

### Injecting the message session

`IMessageSession` is not registered automatically in the container and must be registered explicitly to be injected. Access to the session is provided via `IStartableEndpointWithExternallyManagedContainer.MessageSession`

> [!NOTE]
> The session is only valid for use after the endpoint have been started, so it is provided as `Lazy<IMessageSession>`.

