2016-09-27 4 views
0

Ich habe einen Code geschrieben, der alle Elemente aus einem JSON liest, der die gesamte Konfiguration meiner Anwendung enthält. In diesem Code habe ich eine Eigenschaft namens obj:Wie überwachen Sie die Änderung der Objekteigenschaften?

public static SuperModel obj 
{ 
    get 
    { 
     string json = File.ReadAllText(SettingsConfig.ConfigFilePath); 
     var jsonObj = JsonConvert.DeserializeObject<SuperModel>(json); 
     return jsonObj; 
    } 
} 

SuperModel ist das Klassenmodell, das Beispiel anderer Klassen enthält. Was ich versuche, die json Wert zu erreichen, ist zu aktualisieren und dann eine andere Methode aufrufen, die die Datei mit dem neuen json überschreiben sollte, wie folgt aus:

Settings.obj.GeneralSettings.Language = "english"; 
Settings.Save(); 

Aber ich habe ein Problem, wie kann ich überwachen die Ändern Sie auf obj, zum Beispiel in diesem Fall habe ich die Language Eigenschaft von GeneralSettings ->SuperModel Klasse aktualisiert, ist es möglich, das aktualisierte Objekt mit Save() Methode zu speichern, die die Datei überschreiben? Ich habe nie eine ähnliche Situation erlebt.

Wie kann ich das lösen?

+0

Sie müssen keine Änderungen erkennen, ob Sie das Objekt serialisiert gehst wieder in Datei: wenn es das gleiche, nichts (außer dem Datum der letzten Änderung der Datei) ändert, und wenn es anders, die Datei wird aktualisiert. Für welche _exactly_ benötigen Sie diese Funktionalität und was hat Ihre Recherche gezeigt? Siehe zum Beispiel [Was ist die beste Vorgehensweise, um zu überprüfen, ob ein Objekt geändert wird?] (Http://stackoverflow.com/questions/2071482/what-is-the-best-practice-to-check-if-an-object -ist geändert). – CodeCaster

+0

@CodeCaster ich die JSON-Datei das aktualisierte Objekt in die Datei für die Aktualisierung übergeben müssen, ist das, warum ich ändern diese Frage – Unchained

+0

prüfen erfassen müssen: http://stackoverflow.com/questions/2246777/raise-an-event-whenever -a-propertys-Wert-geändert – Bassie

Antwort

1

Sie stellen die falsche Frage. Wenn Sie keine Objektupdates erkennen möchten, möchten Sie einen Verweis auf eine lokale Variable beibehalten, die bei Ihrer aktuellen return-Anweisung nicht in Betracht kommt.

Um dies zu tun, legen Sie die Einstellungen nur einmal Datei, zum Beispiel in einem statischen Konstruktor:

private static SuperModel _settingsObject; 

static Settings 
{ 
    string json = File.ReadAllText(SettingsConfig.ConfigFilePath); 
    var jsonObj = JsonConvert.DeserializeObject<SuperModel>(json); 
    _settingsObject = jsonObj; 
} 

Dann, wenn ein Anrufer-Objekt der Einstellungen erhält, einfach auf das geladene Objekt zurückgeben:

public static SuperModel obj 
{ 
    get 
    { 
     return _settingsObject; 
    } 
} 

Nun kann jeder Anrufer, der den von Settings.obj zurück SuperModel Instanz ändert, ändert direkt die Instanz durch die Settings-Klasse bekannt. Daher speichert die Save() - Methode die geänderte Instanz:

public static void Save() 
{ 
    string json = JsonConvert.SerializeObject(_settingsObject); 
    File.WriteAllText(SettingsConfig.ConfigFilePath, json); 
} 

Siehe auch Benennungsrichtlinien für .NET. "obj" ist nicht wirklich eine nützliche Kennung.

0

Wenn Sie das Objekt lesen, vorausgesetzt, Sie haben mehrere verschachtelte Ketten, können Sie einen Hash der Objekteigenschaften erstellen und irgendwo speichern (z. B. eine InitialHash Eigenschaft). Wenn Sie nach Änderungen suchen möchten, können Sie die Objekteigenschaften erneut anzeigen und sie mit InitialHash vergleichen. Dies gibt Ihnen nur Informationen, dass die Objekteigenschaften geändert wurden, aber nicht, was genau geändert wurde.

2

Das Problem, das Sie versuchen, in erster Linie zu lösen ist nicht über, wie man Änderungen erkennt (die in der answer linked von CodeCaster gut beschrieben wird). Das Problem hier ist, dass Ihr Design wesentlich fehlerhaft ist.

Sie missbrauchen tatsächlich eine Eigenschaft zu tun, was eine Methode tun soll. Ihre Eigenschaft verhält sich wie ein Generator von Daten und gibt bei jedem Aufruf eine neue Instanz zurück (obwohl sie aus der Werteperspektive die gleichen wären). Sie speichern die deserialisierten Einstellungen niemals dauerhaft, daher ist es nicht überraschend, dass es keine einfache Möglichkeit gibt, die Methode Save() zu implementieren.

Code entkoppeln und ein Nutzungsmuster wie dieses Ziel zu erreichen:

Settings.LoadFromConfig(); 

… do whateever changes you need here … 
Settings.MyConfig.GeneralSettings.Language = "english"; 

Settings.SaveToConfig(); 

Die LoadFromConfig und SaveFromConfig Methoden sollten mit einer SuperModel Eigenschaft arbeiten, die einfach so erklärt werden können:

public SuperModel MyConfig { get; private set; } 

(Der private Setter stellt sicher, dass nur die Klasse Settings eine neue Konfigurationsinstanz erstellen kann.)

Die eigentliche Implementierung von LoadFromConfig und SaveFromConfig sollte für Sie schon einfach sein.

Seitennotiz: Es scheint, dass Ihre Settings Klasse statisch ist. Während es sinnvoll sein könnte, wäre es im Allgemeinen besser, mit einer Instanz zu arbeiten, obwohl es eine singleton ist.

+0

Wie aktualisiert Ihr Code die JSON-Datei? – Unchained

+0

@Unchained Mein Code? Es ist Ihr Code;) Fahren Sie fort und implementieren Sie die 'SaveToConfig' Methode. Es ist trivial, das Gegenteil von einer Last, die Sie bereits implementiert haben. –

Verwandte Themen