C# привязать объект к JSON файлу? - PullRequest
0 голосов
/ 24 января 2020

У меня есть объект:

public class BindObjectToFile
{
    public int Property1 {get; set;}
    public int Property2 {get; set;}

    public BindObjectToFile(string BindingFilePath)
    {
       ...
    }
}

У меня есть Json файл:

{
    "Property1" : 1,
    "Property2" : 2,
}
  • Всякий раз, когда свойство объекта Изменения, я хочу, чтобы Json Файл изменился вместе с ним.

  • Всякий раз, когда свойство в JsonFile Изменения, я хочу Объект для изменения вместе с ним.

  • Я бы хотел, чтобы все дочерние элементы BindObjectToFile легко наследовали эту функциональность, не требуя корректировки для методов получения / установки их свойств. ,

По существу , Я хочу, чтобы объект ощущался так, как будто он хранится в файле, а не в памяти.

Что я попробовал:

  1. Я начал (тупо) Сериализация / десериализация всего объекта на каждом получателе / ​​установщике объекта:
     internal int _property1;
     public int Property1
     {
         get
         {
             return JsonConvert.DeserializeObject<ObjectToFile>(File.ReadAllText(JsonFilePath))._property1;
         }
         set
         {
             _property1 = value;
             File.WriteAllText(JsonFilePath, JsonConvert.SerializeObject(this));
         }
     }

Newtonsoft. json замечательно, но этот подход кажется неправильным, потому что он заставляет меня переписывать всю эту стандартную таблицу для каждого свойства каждого нового дочернего элемента, не сообщая никому, что именно так должен предполагаться мой класс BindObjectToFile использоваться.

Далее я попытался реализовать INotifyPropertyChanged, чтобы сохранить только что сериализованный объект только при изменении свойства. Это было немного лучше, но все равно не учитываются ситуации, когда файл изменяется чем-то другим, кроме этого экземпляра 'BindObjectToFile'.

Я пытался создать Generi c BindObjectToFile, который также реализовал INotifyPropertyChanged. Я сделал это в надежде, что с помощью объекта Generi c я смогу обойти эту проблему без использования наследования, чтобы мне не пришлось искать способ заставить детей писать сумасшедшие методы получения / установки для каждого из их свойств. :

    public abstract class ObjectToFile<T> : INotifyPropertyChanged
    {
        public T _value;
        public T Value
        {
            get
            { 
                return JsonConvert.DeserializeObject<T>(File.ReadAllText(Path));
            }
            set 
            {
                _value = value;
                File.WriteAllText(Path, JsonConvert.SerializeObject(_value ));
            }
        }
        public string JsonFilePath;

        public ObjectToFile(T value, string path)
        {
            _value = value;
            JsonFilePath = path;
        }
   }

Но это все равно заставляет меня инициировать или управлять событиями PropertyChange в дочерних классах при изменении их свойств.

И я не хочу чтобы сделать что-то из этого - я просто хочу родительский класс для решения проблемы, чтобы я мог счастливо создавать дочерние классы, которые ведут себя правильно, и мне не нужно думать об этом.

Это кажется разумным, верно ?

Предостережения:

  • Я не против переписывать / перечитывать весь файл каждый раз при обращении к свойству или при его изменении.
  • В моем контексте я не не волнует скорость. Если кто-то еще откроет один из этих файлов, и мне придется подождать несколько сотен мсек для своей очереди, это не проблема.
  • Все объекты, с которыми я работаю, предельно просты и содержат свойства с основными c типы данных.
  • Все объекты, с которыми я работаю, чрезвычайно малы и редко имеют более пяти или шести свойств.

Спасибо, всем!

1 Ответ

1 голос
/ 24 января 2020

Не думаю, что вы можете изменить только часть файла json, чтобы сохранить только значение свойства, которое было изменено. Если длина значения изменилась, ему пришлось бы переместить остальную часть файла вверх или вниз, и я не думаю, что вы можете сделать это. Так что вам придется каждый раз переписывать весь файл. Который действительно отстой, если какой-то код меняет более одного свойства за раз. Я бы, вероятно, добавил .Save метод или, возможно, даже добавил бы отслеживание изменений с .Commit, когда закончил вносить изменения - поэтому файл записывается один раз для каждого набора изменений. Это также помогает любому, кто использует класс, сообщить, что именно так должен использоваться объект.

Вам также не следует читать / десериализовывать файл каждый раз, когда ссылаются на свойство. Вместо этого я бы попытался использовать класс FileSystemWatcher (настройка свойства Filter), чтобы получать уведомления об изменениях в файле.

Если количество пользователей, просматривающих один и тот же файл, является проблемой, возможно, стоит изучить использование базы данных document / no sql вместо того, чтобы делать это вручную.

...