ASP.NET Core Dependency Injection Integration

Component: NServiceBus
NuGet Package NServiceBus (7.2)
NServiceBus integrates with ASP.NET Core 3.x using GenericHost. For older versions of ASP.NET Core use the community package Community.NServiceBus.WebHost. ASP.NET Core 2.x has a race condition and the community package implements a workaround. It's recommended to upgrade to ASP.NET Core 3.0 and use NServiceBus.Extensions.Hosting package.

ASP.NET Core has an integrated dependency injection (DI) feature. When hosting NServiceBus endpoints inside an ASP.NET Core app, it may be necessary to share components registered for DI between ASP.NET components and NServiceBus message handlers.

Configuring an endpoint to use built-in DI

public void ConfigureServices(IServiceCollection services)
{
    services.AddLogging(loggingBuilder => loggingBuilder.AddConsole());
    services.AddSingleton<MyService>();

    var endpointConfiguration = new EndpointConfiguration("Sample.Core");
    endpointConfiguration.UseTransport<LearningTransport>();

    services.AddNServiceBus(endpointConfiguration);
}

When the sample is run, a web application is started. All web requests received will trigger a message send operation:

applicationBuilder.Run(
    handler: context =>
    {
        if (context.Request.Path != "/")
        {
            // only handle requests at the root
            return Task.CompletedTask;
        }
        var applicationServices = applicationBuilder.ApplicationServices;
        var endpointInstance = applicationServices.GetService<IMessageSession>();
        var myMessage = new MyMessage();

        return Task.WhenAll(
            endpointInstance.SendLocal(myMessage),
            context.Response.WriteAsync("Message sent"));
    });

Message handlers will have dependencies injected at runtime by the configured Inversion of Control container:

public class MyHandler :
    IHandleMessages<MyMessage>
{
    MyService myService;

    public MyHandler(MyService myService)
    {
        this.myService = myService;
    }

    public Task Handle(MyMessage message, IMessageHandlerContext context)
    {
        myService.WriteHello();
        return Task.CompletedTask;
    }
}

Configuring to use shared DI with Autofac

It is also possible to configure ASP.NET Core to use a specific container and still share components between ASP.NET and NServiceBus message handlers. This sample demonstrates how to do this with Autofac using the Autofac.Extensions.DependencyInjection package

This can also be done using other DI libraries.

First, ASP.NET Core is instructed to use a custom container:

webHostBuilder.ConfigureServices(services => services.AddAutofac());

Then, Startup configures both services and the container:

public void ConfigureServices(IServiceCollection services)
{
    services.AddLogging(loggingBuilder => loggingBuilder.AddConsole());

    var endpointConfiguration = new EndpointConfiguration("Sample.Core");
    endpointConfiguration.UseTransport<LearningTransport>();

    services.AddNServiceBus(endpointConfiguration);
}

public void ConfigureContainer(ContainerBuilder builder)
{
    builder.RegisterType<MyService>().AsSelf().SingleInstance();
}

The ConfigureServices method is called by .NET Core at application startup time to register additional services. The ConfigureContainer method registers the components in the container using the container's native APIs.

Related Articles


Last modified