2009-09-18 11 views
6

Ist es möglich, unveränderliche Typen als Konfigurationseigenschaften mit der Konfigurations-API von .NET zu verwenden?Unveränderliche Typen als Konfigurationseigenschaften

Lassen Sie sich sagen, ich habe einen unveränderlichen Typen namens MyClass:

public class ImmutableClass 
{ 
    private readonly int value; 

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

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

Ich mag diese Art als Konfigurationseigenschaft in einem Configuration verwenden:

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

Wenn ich das tue, kann ich serialisieren und deserialisieren Sie MyConfigurationSection nicht, da diese Ausnahme ausgelöst wird:

System.Configurati on.ConfigurationErrorsException: Der Wert der Eigenschaft 'criteria' kann nicht in string konvertiert werden. Der Fehler lautet: Es konnte kein Konverter gefunden werden, der die Konvertierung in/aus der Zeichenfolge für die Eigenschaft 'Kriterium' vom Typ 'FindCriterion' unterstützt.

Wenn ich ImmutableClass von Configuration ableiten, bekomme ich diese Ausnahme, wenn ich versuche, den Konfigurationsabschnitt zu serialisieren und deserialisieren:

System.Reflection.TargetInvocationException: Ausnahme wurde durch das Ziel für einen Aufruf ausgelöst worden . ---> System.Reflection.TargetInvocationException: Vom Ziel eines Aufrufs wurde eine Ausnahme ausgelöst. ---> System.MissingMethodException: Für dieses Objekt ist kein parameterloser Konstruktor definiert.

Ich habe die volle Kontrolle über ImmutableClass, so dass ich implementieren kann, welche Schnittstelle benötigt wird.

Gibt es eine Möglichkeit, die ich in die Konfigurations-API einhängen kann, so dass ImmutableClass auf diese Weise verwendet werden kann?

Antwort

1

Sie können möglicherweise einige TypeConverters verwenden, um den Prozess zu unterstützen (Link zu System.Configurations.ConfigurationConverter).

Die eigentliche Frage ist, warum willst du dir so viel Ärger machen? Es gibt einfach Zeiten, wo es besser ist, sich zurückzulehnen und es zu nehmen, als sich zu streiten. Einige Teile des Frameworks sind frustrierend, wenn Sie versuchen, es auf eine andere Weise zu tun als die für Sie bestimmte.

+0

+1. Danke, das hat gut funktioniert. Ich stimme zu, dass es in den meisten Fällen einfacher ist, mit dem Fluss zu gehen, und das ist auch, was ich normalerweise tue, aber das war ein spezieller Fall ... –

+0

Gut zu wissen ... Ich experimentiere tatsächlich mit unveränderlichen Typen und XAML Serialisierung. Ich hoffe, dass Typkonverter auch für mich arbeiten werden! – Will

4

Persönlich denke ich, dass Sie besser die Daten in der Konfiguration Abschnitt trennen würden (die scheinbar veränderbar sein muss) und wie Sie es in Ihrem Objektmodell darstellen. Es gibt nichts, was Sie davon abhält, zwei Repräsentationen zu haben - eine einfache (DTO/POCO) Version für die Konfiguration und Ihre benutzerdefinierte Version (in diesem Fall unveränderlich) für die tatsächliche Verwendung in Ihrer App.

+0

Ich würde in den meisten Fällen zustimmen, und das ist auch, was ich normalerweise tue, aber das war ein besonderer Fall. –

0

Ich würde diesen Fluch aufgeben, weil die Idee verflucht ist zu scheitern. Alle Konfigurationsabschnittshandler müssen einen (parameterlosen) Standardkonstruktor haben. Dies ist bei Ihrem unveränderlichen Objekt nicht der Fall.

Die einfachste Lösung besteht darin, eine weitere Abstraktionsebene zwischen der Konfiguration und Ihrer Anwendung zu setzen. Sie könnten das Konfigurations-Provider-Muster anwenden, und das würde die "frei für alle" veränderbaren Klassen des Konfigurationsabschnitts in unveränderliche Klassen konvertieren, die dann von Ihrer Anwendung verbraucht würden.

Ich muss sagen, dass so die Konfigurationsabschnitte verwendet werden sollten. Ich weiß, dass es eine Wright-Back-Option gibt, aber ich habe sie nie zuvor benutzt.

Der Code könnte etwa wie folgt aussehen:

Die Konfiguration Handler

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

Nachdem Sie den Konfigurationswert aus der XML-Datei und in ein Objekt, das die Konfiguration Provider Muster verwenden, um zu verbrauchen bekommen haben die Konfiguration in Ihrer Anwendung.

Die Konfiguration Anbieter würde könnte wie folgt aussehen:

public MyConfigurationProvider : IMyconfigurationProvider 
{ 

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

Dies ist, wie ich es tun und es hat mich bisher bedient.

Ich hoffe, es hilft.

+0

Im Normalfall stimme ich Ihnen völlig zu, und das ist auch mein normaler Ansatz, aber das war ein Sonderfall. Ich habe es einfach mit TypeConverts arbeiten lassen, wie von Will vorgeschlagen, und das hat gut geklappt, also ist deine ursprüngliche Behauptung nicht wahr. –

Verwandte Themen