Question

Repeating the ConfigurationPropertyAttribute name three times in the code really bothers me.
It so easy to miss a misspelling or copy/paste a property and forget to update one instance of the name.

Declaring a constant only solves one of these problems. Is there a better way?

I tried reflection, but enumerating the attributes seemed much more trouble, and uglier.

[ConfigurationProperty("port", DefaultValue = (int)0, IsRequired = false)]
[IntegerValidator(MinValue = 0, MaxValue = 8080, ExcludeRange = false)]
public int Port
{
    get
    {
        return (int)this["port"];
    }
    set
    {
        this["port"] = value;
    }
}

I know DRY is just a principle and often, in the real-world, principles must give way to pragmatism. But I'm sure someone has cleaner way?

Was it helpful?

Solution

You can use a non-declarative approach for configuration elements if you want. Examples can be found all over the internet - particularly at Unraveling the Mysteries of .NET 2.0 Configuration where the examples show both methods simultaneously.

class MyConfigurationElement : ConfigurationElement
{
    private static ConfigurationPropertyCollection _properties = new ConfigurationPropertyCollection();
    private static ConfigurationProperty _portProperty = new COnfigurationProperty("port", ..... ); // Will leave as example for you to add validator etc.

    static MyConfigurationElement()
    {
         _properties.Add(_portProperty);
    }

    protected override ConfigurationPropertyCollection Properties
    {
        get { return _properties; }
    }

    public int Port  
    {
        get
        {
            return (int)this[_portProperty];
        }
        set
        {
           this[_portProperty] = value;
        }
    }    
}

OTHER TIPS

Why does using a constant not solve all three problems?

Example:

class MyConfigurationElement : ConfigurationElement
{

    // Use public, private or internal, as you see fit.
    private const string PortName = "port";

    // Add something like this, if you also want to access the string value
    // and don't want to recompile dependend assemblies when changing the
    // string 'port' to something else.
    // public static readonly PortNameProperty = PortName;

    [ConfigurationProperty(PortName, DefaultValue = (int)0, IsRequired = false)]
    [IntegerValidator(MinValue = 0, MaxValue = 8080, ExcludeRange = false)] 
    public int Port  
    {
        get
        {
            return (int)this[PortName];
        }
        set
        {
           this[PortName] = value;
        }
    }    
}

Side Note: If you might also consider using the Configuration Section Designer. Frankly, I have only tested it a couple of years ago and never used it since then, but maybe it also solves your concerns about DRY.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top