1

I am currently trying to design a service that serves as a central place for configuration. However, I noticed there are quite a few services in ConfigurationServices in Startup.cs that use various settings from appsettings.json:

For example:

services.AddDbContext<MyContext>(optionsAction: options =>
{
     options.UseSqlServer(Configuration.GetConnectionString(name: "somekey"));
});

I know if I go into the docker container of a .net core web app and manually change something in appsettings.json with nano and restart the service, it acknowledges the new configuration and uses it. The same with environment variables.

However, I am trying to determine if possible if there was a way to update/modify appsettings.json dynamically and get the services in in ConfigurationServices in Startup.cs to acknowledge the changes without actually restarting the service.

Any help would be much appreciated.

1

2 Answers 2

1

You could use FileSystemWatcher to monitor your appsettings.json file and update your service when the Changed event is raised

EDIT: The simplest implementation I can think of is:

public class YourContextProvider : IContextProvider
    {
        private string _connectionString = "...some default value";

        public YourContextProvider()
        {
            var watcher = new FileSystemWatcher()
            {
                Path = @"..."
            };

            watcher.Changed += (sender, args) =>
            {
                _connectionString = ...access your configuration
            };
        }

        MyContext GetDbContext()
        {
            var optionsBuilder = new DbContextOptionsBuilder<MyContext>();
            optionsBuilder.UseSqlServer(_connectionString);
            return new MyContext(optionsBuilder);
        }
    }

Create a ContextProvider (with your own interface) which will use the FileSystemWatcher and will update its inner _connectionString according to your configuration change. Then whenever you use your DbContext just use the provider to generate it with the current config

 using (var context = _provider.GetDbContext())
   {
            //your code here
   }

Just be careful not to initialize multiple watchers on your appsettings.json which will cause performance issues (you should initilize it only once - maybe use it as a singleton or something...)

Sign up to request clarification or add additional context in comments.

3 Comments

Can you elaborate on how to do this?
Yes could you please explain a bit more. I've looked up FileSystemWatcher and its name does exactly what it says, but how does this tie into the web app acknowledging those changes on the fly without restarting?
Thanks Daniel for providing more context. I’ll start investigating this at some point. The main thing I’m seeking at the moment is that updating the config on the fly and the application responding to such changes is possible, which you seem to be indicating above. Also I found something called Steeltoe for .net core that utilises a Spring Boot config server and states that a .net core apps config can be updated and read at runtime via an actuator, so it must be achievable.
1

This is quite easy to accomplish.

You need to replace the values in appsettings.json with names of environment variables.

Then when you run your Docker container you can pass values for such variables (using -e or --env-file flags for docker run).

In your Dockerfile add something like this:

RUN apt-get update -y && apt-get install -y gettext-base

COPY entrypoint.sh ./
RUN chmod +x ./entrypoint.sh

ENTRYPOINT ["./entrypoint.sh"]

where entrypoint.sh is:

envsubst < ./appsettings.json > /tmp/appsettings.json && cat /tmp/appsettings.json > ./appsettings.json

dotnet <replace_this>.dll $@

This will replace environment variables in appsettings.json with their variables and then start your application when you start the container. So the image will be the same for everybody (build is as usual), but the container will have different appsetings.json files based on the variables passed.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.