App.config reloading


I have seen the same question asked many times.

 

“I changed app.config while the application is running. But the application does not read the change, unless I restart the application. What should I do?”

 

.Net framework will read the app.config once, and never touch the app.config again. That is why you have to restart the application to pick up the change.

 

Why does not .Net framework detect that app.config has changed, and refresh all the config data?

 

The reason is simple, this is not possible in general.

 

Let’s use Raymond’s “imagine this could be done” logic here.

 

Say .Net framework did implement this feature. What exactly will it need to do?

 

First, it will have to know that the app.config file has changed. This can be done by registering file change notification.

 

Once it detects that the app.config has changed, it needs to inform all the componenets that read the app.config.

 

We get a problem right here. How will .Net framework knows which component reads the app.config? Short of a registration mechanism, this is not possible.

 

Say we do have a mechanism for app.config readers to register in .Net framework. When .Net framework detects change in app.config, it will notice each component that app.config has changed. Now what those components should do?

 

In order for the new change to take effect, the component will have to be able to “restart” itself. This means, the component needs to be able to flush the old config data, and data/behavior based on the old config data, then read the new config data, and start fresh from there.

 

This is not always possible. Take binding policy as an example. If the old binding policy says I want version 1 for assembly A, the new policy says I want version 2 for assembly A. There is no way for .Net framework to recover with the new binding policy, if assembly A version 1 is already loaded.

 

Only a subset of config data can be refreshed. Those include config data with no stateful effect, or effect can be easily removed. Cache size is a good example. On change of cache size, you can re-size the cache (and still keep the data), or simply remove the old cache and start a new cache fresh.

 

In general when the app.config changes, the only safe way to make sure all components are consistent is to restart the application. This is the approach .Net framework takes.

 

ASP.Net has the app.config change detection built in. It watches changes on web.config. Once it detects a change, it will shutdown the old application, and starts a new application.

 

Since .Net framework won’t provide the config data refresh feature, if this is important to you, you have to roll your own implementation.

 

Fortunately the Enterprise Library folks understand there is a need for this. They developed “Configuration Application Block” in the latest Enterprise Library release. You can get Enterprise Library from MSDN

 

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/entlib.asp

 

Scott Densmore’s blog (http://blogs.msdn.com/scottdensmore) has several entries for configuration application block. Be sure to check it out.

 

Comments (23)

  1. Why not just support (optional) reloading of the appSettings element (which is what the question you quote is asking for is most cases), and raises an event when this happens.

    If you make the reload optional (<appSettings reloadOnChange="true"/>), nobody could possibly break.

  2. Senkwe says:

    I haven’t investigated deeply yet, but based on the docs it looks like the Config App block in EntLib would still require a restart of the web app.

  3. Nick,

    The notification has some penalty. You have to watch the file for change. If you want to tell people that appSettings has changed, you have to parse the config file. All these are unnecessary penalty for steady state machines.

    And notification is just the beginning. The hard part of how to restart the components that are affected by the change. Unless the component is specifically designed for that(restarable on change), it won’t able to handle the change. Many components are not restartable, including most framework build-in components.

    Senkwe,

    I haven’t investigated the Config App Block deeply either. But I read Scott’s blog. From his blog, it seems the whole idea is a notification system (among other things, like storage abstraction). How do you handle the notification is up to you, which may or may not mean a restart.

  4. Kevin Dente says:

    Hmm, I don’t really buy into the argument that just because not all components can handle dynamic configuration changes, we should assume none of them can. If components are smart enough to deal with this, why not give them a common mechanism to do so.

    Now every app that needs this capability has to reinvent the wheel, which doesn’t seem like a good thing. Also, if multiple components in separate assemblies need to monitor for changes, they all need to set up their own file watchers. I’m not sure if the framework is smart enough to consolodate all of those watcher requests, but if it isn’t, then that’s a lot of overhead.

    Also, it seems like the overhead of dynamic monitoring could be avoided by defining a "ConfigurationChanged" event only starting the file watcher if someone hooks up to the event.

  5. I agree with Kevin. I understand your points, but don’t they add up to a sufficient agruement to not add the feature, escpecially considering it would be a simple, non-breaking change. The question would not have been asked many times if people don’t want the feature.

    Thanks for bringing up an interesting topic, and taking the time to respond to the comments. The interaction is appreciated (even if we don’t agree).

  6. Dean Harding says:

    It’s bad because then what you will get is some components will register for change, and some will not (because the author is too lazy, had too many time constraints, or whatever). Then you’ll hear complaints of "Component X" picks up a change in the app.config, but "Component Y" does not pick up the same change. In this case, it’s not because the infrastrcuture is not there, it’s because "Component Y" didn’t take advantage of it. But a customer isn’t going to be able to see the difference. All they’ll see is that it works for one component but not another.

    Where I work, we have a couple of Windows services written in .NET, and we wanted to be able to make them re-read their config info at runtime if required. We basically ended up just having them monitor the config file and essentially do a re-start whenever it changed (though it’s slightly smarter, in that it only restarts those bits that care about the changes). It’s actually quite a lot of work for the relatively small benefit you get (i.e. just avoiding a restart of the services)

  7. Nick,

    Not sure why you say that I am beaten up. I did not reply yet. But that does not mean I am beaten up. I get a day life to live. After all, it is Sunday:)

    Kevin/Nick,

    It is not a question that whether this feature is useful or not. After all so many people asked the same question, and it means something. The question is whether it makes sense to have a config file change notification build-in in .Net framework. Given the complexity of the problem, the relative small audience of the feature, the potential user confusion (where Dean experienced), among other problems, it makes perfect sense to not have .Net framework build-in support for this, while still have it available in some form for people who are interested. The Configuration Application Block in Enterprise Library is exactly for this purpose.

  8. Ablog says:

    One of the guys in the CLR Fusion team (that thing that handles assembly loading and other related activities) recently blogged about why app.config shouldn’t/ can’t reload. He is getting beaten up a bit in the comments (by me and others) because the reason for not doing the reloading aren’t…

  9. Kevin Dente says:

    Junfeng,

    I totally understand that the feature may not have enough demand to merit inclusion in the framework. What I was objecting to was the idea that dynamic configuration changes can’t be done in a sensible and reasonable way, which it how the original post came across.

    The are definitely situations where these types of dynamic configuration changes are not only useful, but virtually required. As an example, one particularly common scenario is logging configuration, especially in a server class application. Obviously, requiring a restart of the server just to change log levels in unacceptable. Having support from the framework to do this easily would be ideal, but apparently hasn’t bubbled up the priority list yet.

  10. The problem is as a framework, you cannot just add a feature for a specific reason. Features in .Net framework have to be useful for a variety of components. I see great danger for adding this feature, yet I see very small return of investment.

    For your problem, it can be easily solved. You can watch the config file yourself. Or you can have a port open in your service. When logging configuration changes, you send a message to the port, and the service will restart the logging.

  11. I meant beaten up in a friendly robust sort of way – not as a put-down. Sorry if it came across that way. (And its Monday down-under :)).

    Dean: The registry supported re-reading values and getting the updated value, and even had an event notification mechanism (RegNotifyChangeKeyValue). This didn’t cause wide-spread confusion. Having two bits of code that have read and cached any state at different times is a much bigger issue than config file re-loading.

    My main grip is this: We all now agree that refreshing configuration data is, at times, desirable. The argument is whether a large change in the config architecture (going from a config file to the Configuration Application Block ) is worthwhile.

    Picture this conversation:

    Dev-Lead: Find a way to make the app get the current config value if it has changed. The Boss had mandated this requirement, and it makes sense.

    Dev (after spending a day stumbling aroung Google groups and MSDN, and finding this thread): Um, we have to change to the Configuration Application Block to achieve this.

    Dev-Lead: How long will this take?

    Dev: I’m downloading it now. Legal need to check the EULA – it is a bit different from the .NET Framework. I’ve talk to Installer guy, and he needs to work out where to add the Configuration Application Block to the installer. I don’t know if there is a merge module. We need to get it installed on all the dev machines. It will take me a couple of days to integrate it with the app and update all the tests. A week for me all up.

    Dev-lead: So about a man-month total work. Cool. Glad they decided not to support it in the core framework. A man-month is only 20k.

  12. Nick,

    Thanks for explaining it. I was playing soccer today and my body is really beaten up by the opponents. So I am a little sensitive to that phrase now:)

    The conversation is interesting. We usually have the same kind of discussion around feature design, and the end conversation might end like this:

    Dev-Lead: Hmm, One man-month? Not worth it. Let’s just stick to the application restart plan.

    You just have to make trade off.

    The Configuration Application Block is probably too heavy for folks. It is targeting enterprise developers. You can simply register a file change watch for the config file, and handle the rest yourself.

  13. hOSAM says:

    Many might think it is mostly common sense to have the configuration appsettings reader update itself when the config file changes while the responsibility of caching values or reading from appsettings again should be carried out by the caller class itself.

    It is not a feature, it is commonly sensible as you might noticed where all comments are heading.

  14. The point of a framework is to provide a shared, pre-tested, pre-debugged set of commonly needed functionality. Of course in the logging example, there’s a way to code a solution, that’s not the point.

    How many applications need diagnostic logging? Probably most, which is why it ended up as a feature of the framework. How many people writing server applications would be OK with forcing a restart to change logging levels. Probably almost none. So that leaves two options – either everyone writing one of these server apps writes the code to monitor the settings file themselves, or MS codes it once and everyone gets to use that implementation.

    Part of your point is that there isn’t enough demand to justify the feature, which may very well be true.

    But you also seem to be arguing that the feature is somehow dangerous and SHOULDN’T be done no matter what, and that I just don’t argree with.

  15. Kevin Dente says:

    One other thing just occured to me. Doesn’t the ConfigSettings object cache all of the settings after reading it for the first time? Is there any way to get it to dump its cache? If not, then this scenario is even more problematic. Now you how to actually read the config file as XML rather than going through ConfigSettings, and that would be BAD.

  16. Kevin,

    We are talking about two separate things here.

    1. A need to re-load specific settings, like logging.

    2. A generic mechanism to re-load config settings.

    The question is in order to solve 1), do we need to provide 2)?

    My argument is NO.

    But it does not mean 1) should not be addressed. But it can be addressed in a different way. I understand it is not there today. Maybe in the future when the demand grows, .Net framework folks will consider adding support for that.

  17. Kevin Dente says:

    Junfeng,

    And the flip side of that argument is this – if #2 simple and elegently solves #1, as well as other scenarios, why wouldn’t that be the preferred solution?

    Sure, the log guys could come up with a way to re-load log settings. And the app settings team could come up with a way to refresh app settings. And the connection string guys could come up their own way. But I fail to see how that would be better than the general solution.

    In the meantime, I guess I’m stuck with Log4Net for my diagnostic logging needs, as it supports the dynamic configuration changes that real applications need.

  18. Come back to this. I think most folks don’t just expect a change notification. They expect app settings silently update the settings once the config file is updated. This is exactly what I think won’t happen. I just don’t believe people are ready to see app settings changing at real time.

    It is trivial to detech config file change, and parse the config file as XML file. People are just too lazy to parse the file.

  19. sankerkr says:

    Folks –

    I have a enterprise service enabled c# component. The component doesen’t seem to pick up the entries from App.config. Any idea where to add this. Machine config is not an option.

    Please advice.