Configuring Endpoints via Dependency Injection settings

Hi,

I am not sure if this is a good idea or not, but I wanted to configure EndPoints using some sort of HelperClass whos constructor takes a number of params, instantiated via DI
I want to use the HelperClass since the config will be dependent on Dev/Test/Prod and will be re used by many different background services

Host.CreateDefaultBuilder(args)
            .UseNServiceBus(hostBuilderContext =>
            {
                var endpointConfiguration = new EndpointConfiguration("WorkerService");

// use a helper class to get settings via DI somehow
//Get HelperClass from servicecollection where DI passes in settings config etc
                endpointConfiguration manipulated by HelperClass

                // configure endpoint here
                return endpointConfiguration;
            });

Does anyone have any suggestions of a decent approach?

What sort of settings are you expecting to change with each environment? Wouldn’t environmental variables be better configured via environment variables?

We will have many docker containers on AKS using settings via an api to avoid having to repeat the settings and environment variables for each container
The centralised settings will include different transport types:

  • Azure service bus with a different connection string depending on the production region deployed, staging or test

  • RabbitMQ for dev

  • Leaning for local unit tests

Different persistence types and connection strings based on environments above etc

Settings, logging etc will be resolved via DI for each docker container

Hope that makes sense

Especially if you’re using docker containers, I would think ENVVARs are an appropriate tool for passing environment specific variables in. What are you hoping that DI would give you as an extra?

As mentioned, we want to store settings in a centralised location accessed by an api call from every container. Not repeat the same EnVar for every container e.g Transport Type
I.e a setting is only in one location/container which is accessed from every other container

I still feel like a settingshelper or something would be more beneficial than trying to coerce the DI container into doing something that it’s not really good at doing.

To your specific question though, it’s not possible to get the DI container at the .useNServiceBus stage because the container could still be changed by other services.

You could use the HostBuilder context to change things, here’s a sample showing how to access that: Endpoint hosting with the Generic Host • NServiceBus Samples • Particular Docs

Thanks William, your assistance is much appreciated. I was heading down the helper route but was hoping to use the same pattern as with much of my other code. I’ll probably use that

Cheers
Alan

You have access to IConfiguration from the hostBuilderContext.
Using configuration you can abstract how you fetch the values (env vars vs static files etc.)

It would be nice to use the IOptions pattern to inject a strongly typed config object which can have defaults, but I don’t think the service provider is accessible at this stage of the host builder initialization.

It could be possible to register some lazy initialization that gets called after the app startup, but that may require some low level changes in the GenericHost NSB setup classes.

I know NSB dropped config file based setup years ago, but that could be re-visited with the newer IConfiguration abstractions and have a convention for configuration sections for the endpoint, transports, persistence, etc.

1 Like