2009-09-18 9 views
6

¿Es posible usar tipos inmutables como propiedades de configuración con la API de configuración de .NET?Tipos inmutables como propiedades de configuración

Digamos que tengo un tipo inmutable llamada MiClase:

public class ImmutableClass 
{ 
    private readonly int value; 

    public ImmutableClass(int value) 
    { 
     this.value = value; 
    } 

    public int Value 
    { 
     get { return this.value; } 
    } 
} 

me gustaría utilizar este tipo como una propiedad de configuración en un ConfigurationSection:

public class MyConfigurationSection : ConfigurationSection 
{ 
    [ConfigurationProperty("foo")] 
    public ImmutableClass Foo 
    { 
     get { return (ImmutableClass)base["foo"]; } 
     set { base["foo"] = value; } 
    } 
} 

Cuando hago esto, puedo 'serializar y deserializar MyConfigurationSection porque arroja esta excepción:

System.Configurati on.ConfigurationErrorsException: el valor de la propiedad 'criterio' no se puede convertir a cadena. El error es: no se puede encontrar un convertidor que admita la conversión a/desde cadena para la propiedad 'criterio' de tipo 'FindCriterion'.

Si derivo ImmutableClass de ConfigurationElement, consigo esta excepción al intentar serializar y deserializar la sección de configuración:

System.Reflection.TargetInvocationException: Se inició una excepción por el destino de una invocación . ---> System.Reflection.TargetInvocationException: Excepción ha sido lanzada por el objetivo de una invocación. ---> System.MissingMethodException: Ningún constructor sin parámetros definido para este objeto.

Tengo control total sobre ImmutableClass, por lo que puedo implementar la interfaz que sea necesaria.

¿Hay alguna manera de engancharme en la API de configuración para que ImmutableClass se pueda usar de esta manera?

Respuesta

1

Es posible que pueda utilizar un poco de TypeConverters para ayudar con el proceso (enlace a System.Configurations.ConfigurationConverter).

La verdadera pregunta es ¿por qué te quieres causar tantos problemas? Hay algunas veces en las que es mejor recostarse y tomar que luchar. Algunas partes del marco son frustrantes si intentas hacerlo de una forma distinta a la específica que se ha diseñado ...

+0

+1. Gracias, funcionó bien. Estoy de acuerdo en que, en la mayoría de los casos, seguir el flujo sería más fácil, y eso es lo que suelo hacer, pero este fue un caso especial ... –

+0

Es bueno saber ... En realidad estoy experimentando con tipos inmutables y xaml publicación por entregas. ¡Espero que los convertidores de tipos también funcionen para mí! – Will

4

Personalmente, creo que sería mejor separar los datos en la configuración sección (que aparentemente debe ser mutable) y cómo lo representa en su modelo de objetos. No hay nada que le impida tener dos representaciones: una versión simple (DTO/POCO) para config y su versión personalizada (inmutable en este caso) para el uso real en su aplicación.

+0

Estoy de acuerdo en la mayoría de los casos, y eso es lo que suelo hacer, pero este fue un caso especial. –

0

Yo abandonaría esa maldición porque la idea está condenada al fracaso. Todos los manejadores de sección de configuración deben tener un constructor predeterminado (sin parámetros). Este no es el caso con tu objeto inmutable.

La solución más simple es poner otro nivel de abstracción entre la configuración y su aplicación. Podría aplicar el patrón del proveedor de configuración y eso convertiría las clases mutables "gratuitas para todos" de la sección de configuración en clases inmutables que luego serían consumidas por su aplicación.

Debo decir que así es como deben usarse las secciones de configuración. Sé que hay una opción de devolución de Wright pero nunca la había usado antes.

El código podría ser algo como lo siguiente:

El manejador de configuración

public class SectionHandler : ConfigurationSection 
{ 
    [ConfigurationProperty("foo")] 
    public MyObject ConfigurationValue 
    { 
    get { return (MyObject) this["foo"]; } 
    } 
} 

Después de haber conseguido el valor de configuración del archivo XML y en un objeto de utilizar el patrón de proveedor de configuración para consumir la configuración en tu aplicación.

El proveedor de configuración sería podría ser algo como esto:

public MyConfigurationProvider : IMyconfigurationProvider 
{ 

    public MyImmutabble ConfigurationValue 
    { 
    get 
    { 
     var configurationvalue = (MyObject) ConfigurationManager.GetSection("mySection"); 
     return new MyImmutable(configurationvalue.ConfigurationValue); 
    } 
    } 
} 

Así es como lo hago y me ha servido hasta ahora.

Espero que ayude.

+0

En casos normales, estoy totalmente de acuerdo con usted, y ese también es mi enfoque habitual, pero este fue un caso especial. Simplemente lo hice funcionar con TypeConverts como lo sugirió Will, y funcionó bien, por lo que su reclamo inicial no es cierto. –

Cuestiones relacionadas