Using SimpleInjector with NServiceBus to inject IBus Bus property

860 Views Asked by At

I am trying to get acquanited with NServiceBus 5 using its own dependency injection container, and with SimpleInjector, which is our container of choice.

There is a way to tell NServiceBus to inject the

IBus Bus {get;set;}

property into all ASP.NET MVC ApiControllers (or somewhere else) using a custom NServiceBusControllerActivator and NServiceBusDependencyResolverAdapter.

However, we want to use SimpleInjector, and don't have an MVC application, and we don't want to inject the Bus into the controllers directly. The controllers should be light-weight, so the logic is inside of "services", which in turn call Bus.Send(message).

How would you accomplish injecting the Bus property using SimpleInjector? I know that people have tried configuring SImpleInjector with NServiceBus but they just don't work together.

1

There are 1 best solutions below

2
Steven On

As you can read here, me and Kijana had tried to come up with a full solution for integrating Simple Injector with NServiceBus. The problem that Kijana describes however (with appending to collections) has been solved for a long time already. However, there are many other problems with integrating a container with NServiceBus, because NServiceBus implements the conforming container anti-pattern.

I'm not sure if this helps you into the right direction, but you can let Simple Injector build-up instances that are created elsewhere and this allows injecting the IBus into properties, as can be read here and here. In short, you can configure Simple Injector to do property injection like this:

class PropertySelectionBehavior<TAttribute> : IPropertySelectionBehavior
    where TAttribute : Attribute {
    public bool SelectProperty(Type type, PropertyInfo prop) {
        return prop.GetCustomAttributes(typeof(TAttribute)).Any();
    }
}

// Usage:
var container = new Container();
container.Options.PropertySelectionBehavior =
    new PropertySelectionBehavior<ImportAttribute>();

container.RegisterSingle<IBus>(bus);

And you can use the following code to build-up stuff:

public static BuildUp(object instance) {
    InstanceProducer producer =
        container.GetRegistration(instance.GetType(), throwOnFailure: true);
    Registration registration = producer.Registration;
    registration.InitializeInstance(instance);
}