views:

115

answers:

1

I have 2 projects that share some appSettinsg and config sections. Let's say :

  • ProjectA has it's own app.config that contains its unique settings/config sections.
  • ProjectB ditto...

Now in each app.config I want to point to a third shared .config file that contains some common appSettings AND config sections, used by both ProjectA and B.

I know that there is the configSource property that I can use to reference an external file for each configSection, however, from experiment, this approach can only hold ONE config section per external file (by defining the configsection is defined as its root element). I'd like the 'common' file to hold more than one for convenience.

Is this possible?

+1  A: 

You could group all of your settings into your own custom config section. Then of course you can move it all together to a different file using the configSource attribute you mention above.

In the case of the AppSettings, your custom config section could merge it's own values into the normal AppSettings (which are NameValueCollection) using the Add function. This way you shouldn't need to change your client code at all.

As a side, here is some of my base class I use to add "externalConfigSource" attribute to most of my custom elements to allow further file splitting for some of my sub elements (although this is possibly what you are trying to avoid):

public class BaseConfigurationElement : ConfigurationElement
{
    protected override void DeserializeElement(XmlReader reader, bool serializeCollectionKey)
    {
        var fileSource = reader.GetAttribute("externalConfigSource");
        if (!String.IsNullOrEmpty(fileSource))
        {
            var file = new FileInfo(Path.Combine(AppDomainExtensions.ConfigurationFilePath(), fileSource));
            if (file.Exists)
            {
                using (var fileReader = file.OpenRead())
                {
                    var settings = new XmlReaderSettings(){ CloseInput = true, IgnoreProcessingInstructions = true, IgnoreWhitespace = true, IgnoreComments = true};
                    using (var fileXmlReader = XmlReader.Create(fileReader, settings))
                    {
                        var atStart = fileXmlReader.IsStartElement();
                        base.DeserializeElement(fileXmlReader, serializeCollectionKey);
                    }
                }
                reader.Skip();
            }
            else
            {
                throw new ConfigurationErrorsException("The file specified in the externalConfigSource attribute cannot be found", reader);
            }
        }
        else
        {
            base.DeserializeElement(reader, serializeCollectionKey);
        }
    }

    protected override bool OnDeserializeUnrecognizedAttribute(string name, string value)
    {
        if (name == "externalConfigSource")
        {
            return true; // Indicate that we do know it...
        }
        return base.OnDeserializeUnrecognizedAttribute(name, value);
    }
}

public static class AppDomainExtensions
{
    public static string ConfigurationFilePath()
    {
        return ConfigurationFilePath(AppDomain.CurrentDomain);
    }

    // http://stackoverflow.com/questions/793657/how-to-find-path-of-active-app-config-file
    public static string ConfigurationFilePath(this AppDomain appDomain)
    {
        return Path.GetDirectoryName(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
    }
}
Reddog
Just saw your comment above that many sections are already custom config sections, if so, you could extend to work with this "externalConfigSource" code but you'd have to move the reader to the appropriate position in the file to locate the start of your element.
Reddog