1

I'm using NServiceBus 5's default dependency injection features. I want to register a singleton that depends on IBus in the endpoint config.

Ex:

configuration.RegisterComponents(r =>
{
  r.RegisterSingleton(new MyDependency(resolveIBus()));
  ...
}

How can I resolve the instance of IBus in the above pseduo code using NServiceBus's out-of-the-box dependency injection?

Jared Beach
  • 2,635
  • 34
  • 38
  • 2
    `configureComponents.ConfigureComponent(DependencyLifecycle.SingleInstance)` and `IBus` will be injected into you `MyDependency` – tchelidze Oct 31 '20 at 04:16
  • What @tchelidze said. The `IBus` implementation already registered on the container and can just be injected – Daniel Marbach Nov 02 '20 at 09:09

1 Answers1

1

The correct syntax would be:

configuration.RegisterComponents(r =>
{
  r.ConfigureComponent<MyDependency>(DependencyLifecycle.SingleInstance);
  ...
}

The dependency mechanism will investigate the constructor(s) of the MyDependency type and chooses the simplest one it can completely resolve. So, you'll need to create your MyDependency type like this:

public class MyDependency
{
  public MyDependency(IBus bus)
  {
  }
}

More information in the NServiceBus Documentation

If you only know what type of service you need at runtime, you can use the IServiceProvider service like this:

public class MyDependency
{ 
  public MyDependency(IServiceProvider serviceProvider)
  { 
    ...
    var myService = (IMyService)serviceProvider.GetService(typeof(IMyService));
    ...
  }
} 
Marc Selis
  • 833
  • 12
  • 17
  • This does help me achieve what I want to do, but I am curious if there is any way to retrieve the configured component. Other IOC tools I have used normally have a `container.Resolve` method of some sort that will get the configured object – Jared Beach Nov 03 '20 at 14:50
  • I'm not very familiar with the dependency mechanism that is built-in in NServiceBus, but the documentation link that I provided also explains how to configure NServiceBus to use the IOC that you know. – Marc Selis Nov 04 '20 at 21:24
  • 1
    Another way to achieve what you want is to use the `IServiceProvider` service like this: public class MyDependency { public MyDependency(IServiceProvider serviceProvider) { var myService = (IMyService)serviceProvider.GetService(typeof(IMyService)); } } – Marc Selis Nov 04 '20 at 21:27
  • I think that completely answers it. Mind adding that to your answer? – Jared Beach Nov 05 '20 at 02:16
  • 1
    I extended my answer with an IServiceProvider example... – Marc Selis Nov 06 '20 at 14:22
  • @MarcSelis using a service locator is generally considered a bad practice, so i wouldn't advertise it. [ServiceLocatorisanAnti-Pattern](https://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/) – tchelidze Nov 10 '20 at 17:03
  • @tchelidze I am aware of that and I try to avoid it as much as possible, but there are use cases (most of the times in framework-like code) where you only know what service type you need at runtime and then you have no other possibility than to use `IServiceProvider`or `IServiceLocator` or the likes... – Marc Selis Nov 11 '20 at 18:52