Evite repetir el nombre de la propiedad 3 veces usando ConfigurationPropertyAttribute

Repitiendo el ConfigurationPropertyAttribute nombre tres veces en el código realmente me molesta.
Es muy fácil pasar por alto un error ortográfico o copiar/pegar una propiedad y olvidarse de actualizar una instancia del nombre.

Declarar una constante solo resuelve uno de estos problemas. ¿Hay una mejor manera?

Probé la reflexión, pero enumerar los atributos parecía mucho más problemático y más feo.

[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;
    }
}

Sé que DRY es solo un principio y, a menudo, en el mundo real, los principios deben dar paso al pragmatismo. Pero estoy seguro de que alguien tiene una forma más limpia?

preguntado el 03 de mayo de 12 a las 18:05

2 Respuestas

Si lo desea, puede utilizar un enfoque no declarativo para los elementos de configuración. Se pueden encontrar ejemplos en Internet, particularmente en Desentrañando los misterios de la configuración de .NET 2.0 donde los ejemplos muestran ambos métodos simultáneamente.

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;
        }
    }    
}

contestado el 03 de mayo de 12 a las 19:05

+1: Siempre descuido esa forma de hacerlo ;-) Esto también tiene la ventaja de ser más rápido (durante el tiempo de ejecución) que la forma declarativa (que es la razón por la que lo usaron para la configuración de WCF/System.ServiceModel que es en los detalles - lo siento, no puedo recordar la fuente donde leí eso). Podría decirse que eso tiene el problema de que uno "olvida" agregar/eliminar una propiedad de configuración a la colección, pero solo proporciona una propiedad de obtención/establecimiento en el código. Bueno, supongo que con cualquier enfoque, al final tienes que saber lo que estás haciendo y emplear la "artesanía" adecuada. - cristiano.k

¿Por qué el uso de una constante no resuelve los tres problemas?

Ejemplo:

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;
        }
    }    
}

Nota al margen: Si también puede considerar usar el Diseñador de la sección de configuración. Francamente, solo lo probé hace un par de años y nunca lo usé desde entonces, pero tal vez también resuelva sus preocupaciones sobre DRY.

contestado el 04 de mayo de 12 a las 04:05

Creo que en el sentido de copiar/pegar/editar errores. Copias tu propiedad Port para hacer una propiedad Foo. Cambia la declaración del atributo de PortName a FooName, pero olvida cambiar las referencias get/set, y se compila bien. Una solución que resuelve todos los problemas permite especificar el nombre una vez y solo una vez en lugar de repetirlo tres veces. Pero el uso de constantes sigue siendo una mejora con respecto a las cadenas mágicas repetidas. - hacha - hecho con SOverflow

@hatchet estuvo de acuerdo. Sin embargo, creo que no deberíamos complicar demasiado las cosas aquí. Un poco de cuidado y buenas pruebas detectan estos problemas fácilmente. Además, aún queda el problema de los archivos XSD, que debe crear de todos modos (para obtener un soporte de intellisense adecuado al editar archivos app.config). Ahí tienes el nombre (atributo) de nuevo. Aparte de la generación de código/XSD de una sola fuente, no hay nada que pueda ayudar aquí. - cristiano.k

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.