colin-higgins
colin-higgins

Reputation: 1117

NServiceBus Host Console Using Wrong App Config

tldr - NServiceBus.Host.exe hijacks my app.config in debug mode

When using the configuration manager, I am not able to access the appSettings for the project I am calling code within.

I am using self host with the NServiceBus Host nuget package, version 4.4.2

namespace EnrollmentService.Reporting
{
    public class EndpointConfig : IConfigureThisEndpoint, AsA_Server
    {
        public EndpointConfig()
        {
            //TODO: WHAT IS HAPPPEEENNIIINNNGG
            var url = ConfigurationManager.AppSettings["configurationKey"];

            var config = ConfigurationManager.OpenExeConfiguration("EnrollmentService.Reporting.dll");

            var nsbHostConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        }
    }
}

The variable 'url' comes back null. The variable 'config' is what used to be the configuration context for this application. The variable 'nsbHostConfig' is the actual configuration context for the application.

Again, the expected path for the configuration is "EnrollmentService.Reporting.dll.config", but the actual path is "NServiceBus.Host.exe.config". The NServiceBus config file doesn't exist.

This seems to be a machine specific problem, as it works as expected, using the "*.dll.config" on other machines.

It makes sense to me that the executable that ends up calling code should be the config for the "running" application, but previously, it was using the expected *.dll.config. It also makes sense to me that NServiceBus would be changing the configuration context, because for debugging purposes, the host runs as a console app, but for deployments, it is installed as a windows service. It would be silly to need to swap out your config files in your bin whenever you needed to develop.

Why would the operating context for my self host application switch to use the NServiceBus executable's config?

UPDATE:

Below, is what SHOULD be happening, but it is not

https://github.com/Particular/NServiceBus.Host/blob/develop/src/NServiceBus.Hosting.Windows/EndpointTypeDeterminer.cs

Looking at the NServiceBus source code, if your EndpointType is not specified in your app.config, the EndpointTypeDeterminer.cs finds your EndpointType by assembly scanning for the type IConfigureThisEndpoint. It then finds the path to your app.config file by calling the below code on the type it finds:

public string EndpointConfigurationFile
{
    get { return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, type.Assembly.ManifestModule.Name + ".config"); }
}

That configuration file path is then used through System.AppDomainSetup to call System.AppDomain.CreateDomain

Upvotes: 1

Views: 1227

Answers (2)

colin-higgins
colin-higgins

Reputation: 1117

Okay, I have found the problem. This one was a doozy. In a nutshell, the configuration swap out was a red herring.

In separating out some of my endpoints into separate solutions and creating NuGet packages, I incremented the version number of a dependency, RestSharp, from 104.1.0 to 105.0.1.

Rest sharp changed the signature of it's RestClient. The BaseUrl became a Uri instead of a string.

I was creating an instance of our ConfigurationAccessService in the constructor of this endpoint, which created a RestClient in it's constructor.

Now, NServiceBust.Host will create an instance of EndpointConfig TWICE. First, just to try it, and get some metadata. Second, to actually use. The configuration is not swapped out until the second instance.

So when RestSharp was upgraded, the first instance failed, because there would be no appSettings. The expected appSetting was null, and you can't initialize a Uri with a null string, it will throw an exception. Meaning that the service would fail startup every time.

Upvotes: 0

Hash
Hash

Reputation: 851

Configuration file of the "running" app is used, not the dll's config.

How do you invoke your service? Using NServiceBus.Host.exe? Then that exe's configuration file will be used all the way. Copy all your settings from dll's config and paste them into exe's config file to make it work. If exe's config is not present in the application folder create it.

Upvotes: 2

Related Questions