0

I am working on removing obsolete/unused pieces of configuration from a .NET product starting with appSettings. There are multiple solutions and I've noticed that appSettings can be in a .config file in one project but which are somehow read in another project, sometimes in a separate solutions.

What I'm trying to figure out:

  • How to tell from which .config file a particular configuration setting is read?
  • How to tell which configuration settings can be removed?

Some easy cases:

  • there is an appSetting with a key like 'ResetHelloWorldWhenFooBarHappens'. I can full text search all solutions and it only appears in the app.config file I'm cleaning up. It can be removed.
  • there is an appSetting which Visual Studio Ctrl + F (search document/project/solution) shows me is used everywhere and is holding the project together. It can be removed but the application will fail.
  • there is an appsetting which is not used anywhere in the solution but the key name is included in an enum in a separate solution named Shared which handles logging for several solutions. I can remove it and see that logging stops working for that solution.

Some tricky cases:

  • there is an appSetting in a config file which is not being used in that project but it is used in a different project which does not have it's own config files. I can look at the project references (or dependencies if its a newer SDK style project), see there is some kind of connection between the projects and guess that the appSettings is being used.
  • there is an appSetting with a generic name like 'path' which appears in various other config files and is read/gotten in obscure code by various projects and solutions. I don't know what to do. I could leave all of those appSettings alone even if most of them do nothing. If I remove some/all of them it's difficult to figure what has changed or if anything has broken.

Thanks in advance.

Astrophe
  • 113
  • 4
  • Searching for the specific strings in all files in the repository and carefully analysing the results is one way. – Rik D Jun 22 '21 at 17:21
  • 1
    This here may answer your question: [How to approach the BIG BALL OF MUD pattern from the architectural POV?](https://softwareengineering.stackexchange.com/questions/347240/how-to-approach-the-big-ball-of-mud-pattern-from-the-architectural-pov). It is more general, of course, but this question here seems to be about configuration code which has become a "big ball of mud", and the answers to solve this (which will make it possible to identify unused parts in config, for example) are the same as for any other degraded parts of a software system. – Doc Brown Jun 23 '21 at 04:22
  • @RikD In a repository, there are appSettings which only appear in an app.config file and the key is not used anywhere else (in the repo/solution) but still I don't know if they can be removed. I disabled logging by taking this approach - luckily it was easy to detect. I appreciate your comment about careful analysis but it's sort of like restating the problem. What I'm trying to figure out is how to do the careful analysis in a way that is manageable. – Astrophe Jun 23 '21 at 09:13
  • @DocBrown Thanks, it's a bit too general for my needs but I've added a few things to my reading list. I think my question boils down to this: `Can I take a configuration file and see which settings are obsolete for a multi repository product?` It might turn out that it's just not the right approach. Perhaps someone can explain how it works and hopefully what to do instead. – Astrophe Jun 23 '21 at 09:57
  • I guess you could write a linter that picked up on the standard ways of accessing the config but im not surte it would be much better than seatching for "path" with the quotes included – Ewan Jun 23 '21 at 20:27
  • @Ewan Thanks. Based on DocBrown's answer and other discussions/reading, I think that right now I can do a partial clean-up of the configuration, removing things which appear to be unused and potentially breaking things, fixing them and learning more about how the system works. After that, I will propose that we need to refactor the code to identify the remaining obsolete configuration settings. – Astrophe Jun 24 '21 at 06:11

1 Answers1

2

The right approach is probably to refactor the code first and encapsulate all "appSettings" access in a central place in each project. This is specificially true for the "obscure" code, as you described it, which accesses the appsettings of other applications. The central config classes or components should provide an API which does not allow passing strings as config item keys, all key strings should be strictly kept in the capsule.

Then, identifying the unused parts of the configuration files should become a lot easier, since now one can restrict the analysis to a rather small part of the code base.

Of course, refactoring requires a certain testing effort, and I guess you were looking for a simpler solution. However, take my word for it: I fear there is none. Once a code base makes access to global resources like configuration files in arbitrary, unrestricted ways, it has become an almost unmaintainable mess. The only way to deal with this is to bite the bullet, rework the technical debt and clean the mess up.

Doc Brown
  • 199,015
  • 33
  • 367
  • 565
  • Something tells me there is a lower level approach but maybe not. At the moment I'm engaged in a type of brainstorming of ifs buts and maybes. If I knew how to hit a breakpoint for each appSetting in code then perhaps that would be a manageable way through the problem. Or if I could see which config files were being handled by the CLR Loader. The funny thing is that I was given this work as a step to enable us to refactor the code but perhaps we need to refactor the code to enable this type of clean-up. – Astrophe Jun 23 '21 at 12:03
  • I've read your answer a few times and it's starting to make more sense to me. At the moment I'm not sure what you mean about not passing strings as config item keys and keeping key strings in the capsule. – Astrophe Jun 24 '21 at 06:27
  • @Astrophe: if a key string like "'ResetHelloWorldWhenFooBarHappens" can occur everywhere in the code base, and passed into a function `MySettingsWrapper.GetString(string key)`, one cannot easily determine if the key is not created dynamically by string concatenation, so a global search will not reliably tell you if that string may still be required. But if `MySettingsWrapper` provides a method `bool ResetHelloWorldWhenFooBarHappens()` instead, and the key string "ResetHelloWorldWhenFooBarHappens" is kept in `MySettingsWrapper`, it will be clear it is required (or not). – Doc Brown Jun 24 '21 at 07:33
  • It sounds like there is there an additional human step to maintain the bool methods when adding and removing appSettings. Is that how you meant it? – Astrophe Jun 24 '21 at 09:06
  • @Astrophe: "additional human step" - not sure if I understand what you mean. Additional, compared to what? – Doc Brown Jun 24 '21 at 10:56
  • I don't know if I've lost anything by putting it into my own words. What I understand, in each project, there is an appsettings reader which is a store of app keys and it is used to get the value of appsettings from a config file. To read an appsetting in code you get it through the appsettings reader. – Astrophe Jun 24 '21 at 11:32