Getting Started
Architecture
NServiceBus
Transports
Persistence
ServiceInsight
ServicePulse
ServiceControl
Monitoring
Samples

Dependency Injection Changes in NServiceBus Version 6

Component: NServiceBus

This is part of the NServiceBus Upgrade Guide from Version 5 to 6, which also includes the following individual upgrade guides for specific components:

Feature Details
Transports
Persistence
Hosting
Other

Configure type removed

In NServiceBus version 5, the Configure type is used to provide runtime access to the local endpoint address, scanned types, etc, via dependency injection. In version 6, these values are accessed as follows:

Immutable

The default container used internally is immutable once the endpoint is started.

Settings

Settings can be accessed via the FeatureConfigurationContext, see Features for more details. Runtime access via dependency injection is provided by taking a dependency on the ReadOnlySettings type.

Builder

This is no longer supported in NServiceBus version 6. Instead of using IBuilder directly, use a specific dependency injection library.

Scanned types

Access to types found during assembly scanning is provided via Settings.GetAvailableTypes().

Local address

Access to the endpoint address is provided via Settings.LocalAddress().

Encryption service

It is no longer possible to access the builder to create an encryption service. If dependency injection access is required, use it directly in the factory delegate in the RegisterEncryptionService method.

Conventions

Conventions are no longer injected. Conventions must be retrieved with Settings.Get<Conventions>() over ReadOnlySettings.

Dependency injection

Explicitly setting property values via .ConfigureProperty<T>() and .InitializeHandlerProperty<T>() is deprecated in NServiceBus version 6. Instead configure the properties explicitly using:

endpointConfiguration.RegisterComponents(
    registration: components =>
    {
        components.ConfigureComponent(
            componentFactory: builder =>
            {
                return new MyHandler
                {
                    MyIntProperty = 25,
                    MyStringProperty = "Some string"
                };
            },
            dependencyLifecycle: DependencyLifecycle.InstancePerUnitOfWork);
    });

IConfigureComponents no longer registered

To access IConfigureComponents at runtime, create a new feature and put the following code in the .Setup method

var container = context.Container;
container.ConfigureComponent(
    componentFactory: builder => new MyDependency(container),
    dependencyLifecycle: DependencyLifecycle.InstancePerCall);

Instances passed to the configuration API are no longer disposed

var builder = new ContainerBuilder();
builder.RegisterInstance(new MyService());
var container = builder.Build();
endpointConfiguration.UseContainer<AutofacBuilder>(
    customizations: customizations =>
    {
        customizations.ExistingLifetimeScope(container);
    });

While the above example shows how an existing DI instance can be passed into the configuration API using Autofac, the same behavior can be applied to all of the currently supported dependency injection. Previous versions of DI treated the externally passed-in DI instance as if it were owned by the DI adapter and disposed the DI when the bus was disposed. This behavior changed in NServiceBus version 6. When a DI customization is passed in (as in the above example), then the DI instance is no longer disposed. It is the responsibility of the DI owner to dispose the DI instance.

endpointConfiguration.UseContainer<AutofacBuilder>();

The above example shows how a new DI instance can be assigned using the configuration API. While the DI instance used in this example is Autofac, the same behavior can be applied to all of the currently supported dependency injection. When passing a new DI instance, the endpoint owns that instance and will also be responsible for disposing it when endpoint stopped.

Related Articles