0

Context: I'm working on a library (let's call it InternalLib) to be used by coworkers, but from their point of view, it's an external assembly. In InternalLib, I need to use an external library too (let's call it ExternalLib), which I merged into InternalLib using ILMerge.

Both InternalLib and ExternalLib need to use configuration from the app.config. I know my coworkers can define configSections and linked applicationSettings for InternalLib and ExternalLib in their app.config, but is there a way I can read config from a different config file? (for example, InternalLib.dll.config) I would rather like to give them a dll and a .config than to ask them to add n config sections into their configuration file.

I could change InternalLib to read a configuration file into a Configuration object using ExeConfigurationFileMap, but I have no control over where ExternalLib gets it's configuration from. I mean that even if I get ExternalLib's config into a Configuration object, I can't tell ExternalLib to use that object instead of, for example, Settings.Default.[...], can I?

Tipx
  • 7,367
  • 4
  • 37
  • 59
  • It seems to me that you're trying to read configuration from an XML file. In that case, check this out: http://msdn.microsoft.com/en-us/library/eh3exdc4.aspx – AndyAndreiH Oct 29 '13 at 14:17

2 Answers2

1

You can change the configuration file a project uses with the following:

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", AppDomain.CurrentDomain.BaseDirectory + confFolder + "app.config");

To reset afterwards if needed

    private void ResetConfigMechanism()
    {
        typeof(ConfigurationManager)
            .GetField("s_initState", BindingFlags.NonPublic |
                                     BindingFlags.Static)
            .SetValue(null, 0);

        typeof(ConfigurationManager)
            .GetField("s_configSystem", BindingFlags.NonPublic |
                                        BindingFlags.Static)
            .SetValue(null, null);

        typeof(ConfigurationManager)
            .Assembly.GetTypes()
            .Where(x => x.FullName ==
                        "System.Configuration.ClientConfigPaths")
            .First()
            .GetField("s_current", BindingFlags.NonPublic |
                                   BindingFlags.Static)
            .SetValue(null, null);
    }

Further reading

Community
  • 1
  • 1
Sam Leach
  • 12,746
  • 9
  • 45
  • 73
  • It's really interesting, and actually does what I wanted, aside from one slight problem. As you're aware, it resets the config for the whole application. I'll look into "saving the old config and reloading it afterward", but I'm afraid it can cause undesired effects if the calling application has modified some settings, and hasn't saved them yet. Looking into it. – Tipx Oct 29 '13 at 14:30
  • I haven't found a clean way to temporarily save pending changes to configuration, load my config, use it, and restore the temporary state, but since it's highly unusual for an application to change settings, and not save them at that moment, I'll just add a note about that in my user-doc and proceed this way. Thanks Sam. – Tipx Oct 29 '13 at 16:37
0

You can use XmlSerializer, e.g. (simplified, no error handling etc.):

public class Config<T> where T : class
{
    public static T Load()
    {
        using (var reader = new StreamReader("config.xml"))
        {
            return (T)(new XmlSerializer(typeof(T))).Deserialize(reader);
        }
    }
}
Andriy Tylychko
  • 15,967
  • 6
  • 64
  • 112