Question about new DI extension support

Hi,
I’m having trouble determining what exactly needs to change in my project in response to this https://particular.net/blog/nservicebus-now-supports-microsoft-extensions-dependencyinjection:

Looking at your sample downloaded from here:

the pertinent section of new code looks like this:

var containerSettings = endpointConfiguration.UseContainer(new DefaultServiceProviderFactory());
containerSettings.ServiceCollection.AddSingleton(new MyService());

The analogous section of our existing NSB configuration is using the following:

 endpointConfiguration.UseContainer<ServicesBuilder>(customizations =>
   {
      customizations.ExistingServices(services);
      customizations.ServiceProviderFactory(sc =>
         {
            var container = new UpdateableServiceProvider(sc);
            return container;
         });
    });

where ServicesBuilder comes from NServiceBus namespace,
and “services” refers to an IServiceCollection that we’ve already built up out of a lot of other code external to our “ConfigureNServiceBus” logic that is passed into it.

With the existing code, we’re already able to inject whatever classes we need to into our Handlers using standard constructor injection.

So I’m trying to figure out
a) whether I need to change and
b) if I do, how can I make this change without having to move all of my configuration into the NServiceBus configuration section so I can manually add each dependency with proper scope to this new container?

I can’t really just do a “foreach” adding every service from ‘services’ into the containerSettings using AddSingleton because each of these services was originally configured with the proper scope, as they aren’t all Singletons, so just trying to port them from services could be messy, non maintainable code.

Worst case scenario I guess I’d just have to mix all the configuration together but making my config less clean doesn’t seem like the right solution, so wanted to get your take. I could also potentially break up our NSB config into two parts, creating this container first before doing any other service config, then passing it into all the other config methods to add their services to it, then doing the final NSB config that depends on other previous activities.

But, before I go through the effort I want to understand if the code we’re using is actually part of what is deprecating because that wasn’t super clear from the documentation or examples.

Thanks in advance,
Anye M. Shafer

Please be aware that the ServiceBuilder and API you’re referring to seems to come from the NServiceBus.MSDependencyInjection package which isn’t an official package. This is a community built package which isn’t supported by Particular Software.

No you don’t have to change immediately. Just keep in mind that we do not provide support or maintain the community package though. As long as the package is supported you can of course continue to use it. However, the “officially supported” way to integrate with Microsoft.Extensions.DependencyInjection is via the NServiceBus.Extensions.DependencyInjection package.

If you have an existing IServiceCollection, you can for example just merge that into the NServiceBus managed collection via containerSettings.ServiceCollection.Add(existingServiceCollection);. Would that approach work for you?
The AddSingleton shown in the documentation is just an example usage of a custom registration, there is no need to register services as singletons.

Does that help?

Thanks for the clarification, I think you’re right, that would be a pretty easy change. Somehow I missed that your new interface supported passing in an existing service collection vs. just adding them individually.

ETA: And here’s why I missed it!
@Tim – when I try this suggestion,
containerSettings.ServiceCollection.Add() is expecting a ServiceDescriptor not an IServicesCollection.
I’ve tried casting and that is not allowed.
"Argument type ‘Microsoft.Extensions.DependencyInjection.IServiceCollection’ is not assignable to parameter type ‘Microsoft.Extensions.DependencyInjection.ServiceDescriptor’.

This seems weird since Microsoft’s IServiceCollection.Add() interface does allow you to pass in another IServicesCollection (according to this: https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection?view=dotnet-plat-ext-3.1)

but the NServiceBus.ContainerSettings.ServiceCollection appears to only supports one Add extension (this IServiceExtension, ServiceDescriptor) where “this IServiceExtension” is the container’s, not the existing.

I have added a reference to NServiceBus.Extensions.DependencyInjection package, though it doesn’t appear to be used by the referencing code. Is there some other reference necessary to use Add with an existing IServiceCollection as you have suggested? Perhaps you could add this to your super-simple example project?

Thanks in advance,
Anye

The mentioned Add method is located in the Microsoft.Extensions.DependencyInjection.Extensions namespace, have you made sure to import that namespace (using Microsoft.Extensions.DependencyInjection.Extensions;)?

That did the trick. Sorry, I’m clearly not working at my best right now.

Thanks for the assistance!

Glad to hear it worked :+1: