views:

314

answers:

2

Is there a way for me to include a simple array of strings, or List<string> on my custom subclass of ConfigurationSection? (Or an array or generic list of simple data objects, for that matter?)

I'm becoming familiar with the new (and VERY verbose) ConfigurationSection, ConfigurationElement, and ConfigurationElementCollection classes, but I'm by no means an expert yet.

It seems like ConfigurationSection should handle simple collections/lists on its own, without me having to create a custom ConfigurationElementCollection subclass for each and every one. But I haven't found any reference to this ability online.

Edit: accepting Dan's response as the answer, since it's probably the closest thing I'm going to get to the "old style" configSections. I always found it easy, flexible, and elegant that any XmlSerializable object could easily become a configSection. I'm sure the new framework is more powerful; however it's sad that it is SO cumbersome for simple configuration contructs, that we're reduced to going back to String.Split().

+1  A: 

OK, you asked for simple. Well, the simplest way to store a series of strings would be to use a delimited list (say, comma separated). That way you can store it in just one element (say in appSettings).

<add key="weekDays" value="Monday,Tuesday,Wednesday,Thursday,Friday"/>

Of course, this has drawbacks but in most cases works well for a simple list. You can then use String.Split() to convert it back to an array/list.

Otherwise you are back to ConfigurationSection elements which, I agree, are very verbose and clumsy to work with. But I don't know of any other way, I'm afraid (but am happy to be proved wrong!).

Dan Diplo
Dan D - thanks, but you're right, I wasn't looking for something QUITE that simple! :) I've used delimited lists and String.Split before, and I'm sure I'll use it again. But I was hoping for something a little more elegant. Maybe someone else will reply with something we've missed.
mikemanne
I didn't think so, but sometimes developers overlook the obvious. It's in our nature!
Dan Diplo
A: 

Here's a simple example.

Note, I had to put a space after the < of the xml and a space before the > of the xml to get it to show up.

//START CODE

//MyCompany.MyProject.csproj which results in MyCompany.MyProject.dll //Add a Folder called "Configuration"

namespace MyCompany.MyProject.Configuration { using System; using System.Collections.Generic; using System.Linq; using System.Text;

using System.Configuration;


public class TransformationToDirectoryMapping : ConfigurationElement
{

    private const string FRIENDLY_NAME = "FriendlyName";
    private const string PICKUP_FOLDER = "PickupFolder";

    [ConfigurationProperty(FRIENDLY_NAME, DefaultValue = "", IsKey = false, IsRequired = true)]
    public string FriendlyName
    {
        get
        {
            return ((string)(base[FRIENDLY_NAME]));
        }
        set
        {
            base[FRIENDLY_NAME] = value;
        }
    }

    [ConfigurationProperty(PICKUP_FOLDER, DefaultValue = "", IsKey = true, IsRequired = true)]
    public string PickupFolder
    {
        get
        {
            return ((string)(base[PICKUP_FOLDER]));
        }
        set
        {
            base[PICKUP_FOLDER] = value;
        }
    }



}

//-----------------------------------------------------------------------

//-----------------------------------------------------------------------

[ConfigurationCollection(typeof(TransformationToDirectoryMapping))]
public class TransformationToDirectoryMappingCollection : ConfigurationElementCollection
{

    protected override ConfigurationElement CreateNewElement()
    {
        return new TransformationToDirectoryMapping();
    }

    protected override object GetElementKey(ConfigurationElement element)
    {
        return ((TransformationToDirectoryMapping)(element)).PickupFolder;
    }


    public TransformationToDirectoryMapping this[int idx]
    {
        get
        {
            return (TransformationToDirectoryMapping)BaseGet(idx);
        }
    }

    new public TransformationToDirectoryMapping this[string key]
    {
        get
        {
            return (TransformationToDirectoryMapping)BaseGet(key);
        }
    }
}

//-----------------------------------------------------------------------

//-----------------------------------------------------------------------

public class TransformationToDirectoryMappingConfigSection : ConfigurationSection
{
    private const string TRANSFORMATION_TO_DIRECTORY_MAPPINGS = "TransformationToDirectoryMappings";

    [ConfigurationProperty(TRANSFORMATION_TO_DIRECTORY_MAPPINGS)]
    public TransformationToDirectoryMappingCollection TransformationToDirectoryMappingItems
    {
        get { return ((TransformationToDirectoryMappingCollection)(base[TRANSFORMATION_TO_DIRECTORY_MAPPINGS])); }
    }
}

//-----------------------------------------------------------------------

//-----------------------------------------------------------------------

public static class MyRetriever
{
    public static readonly string MAPPINGS_CONFIGURATION_SECTION_NAME = "TransformationToDirectoryMappingsSection";

    public static TransformationToDirectoryMappingCollection GetTheCollection()
    {
        TransformationToDirectoryMappingConfigSection mappingsSection = (TransformationToDirectoryMappingConfigSection)ConfigurationManager.GetSection(MAPPINGS_CONFIGURATION_SECTION_NAME);
        if (mappingsSection != null)
        {
            return mappingsSection.TransformationToDirectoryMappingItems;
        }
        return null; // OOPS!

    }
}

}

//XML for config file:

< ?xml version="1.0" encoding="utf-8"? > < configuration > < configSections > < section name="TransformationToDirectoryMappingsSection" type="MyCompany.MyProject.Configuration.TransformationToDirectoryMappingConfigSection, MyCompany.MyProject"/ > < /configSections >

< TransformationToDirectoryMappingsSection > < TransformationToDirectoryMappings > < add FriendlyName="Hello" PickupFolder="C:\WUWUTemp\pickups\pickup11\" / > < add FriendlyName="GoodBye" PickupFolder="C:\WUWUTemp\pickups\pickup12\" / > < /TransformationToDirectoryMappings > < /TransformationToDirectoryMappingsSection > < /configuration >

granadaCoder
Thanks for the reply - especially to a relatively old question. :) Unfortunately, that's still not quite what I'm looking for. You have an array of 1st-class objects, each containing a couple strings. All I want is an array of strings. Using "old-style" config sections, I was able to do that without creating a custom object. I was hoping there's a way to do that within the new config framework, without necessitating creation of an object to essentially wrap a List<string>.
mikemanne