Перейти к содержанию

API для работы со storage-объектами

API для работы со storage-объектами

Данное API предназначено для работы со storage-объектами, такими как IDictionary<string, object> и IList.

Интерфейс IStoragePathParser описывает объект, выполняющий синтаксический анализ строкового представления пути в storage-объекте. Интерфейс IStoragePathResolver описывает объект обеспечивающий выполнение действий (получение и задание значения) с элементами storage-объекта.

Формат пути в storage-объекте

Путь может состоять из следующих элементов:

  1. Разделителя элементов пути.

    В качестве разделителя используется символ точки – ..

    Note

    Для экранирования символа используется обратная косая черта – \.

    Note

    Не может использоваться в качестве самостоятельного символа. Может располагаться только между ключами и/или индексами или символами перехода к родительскому элементу.

  2. Ключа.

    Ключ – это строка, по которой выполняется доступ к объекту, расположенному в объекте, реализующем интерфейс IDictionary<string, object>.

    Примеры: Key, \.key, \..

  3. Индекса.

    Индекс – это порядковый номер элемента, расположенного в объекте, реализующем интерфейс IList.

    Примеры: [0], [0][1], Key[0].

  4. Подстановочного символа.

    1. [] – указывает на необходимость обхода всех элементов списка.

      Примеры: [], [][], Key[].

    2. ^ – указывает на необходимость перехода к родительскому элементу пути.

      Примеры: Key.^, [].^.

Примеры работы с путями

В примерах будет использоваться объект:

{ "First": { "Second": [ { "Third": [ { "Forth": "Test11" }, { "Forth": "Test12" } ], "ID": "ID1" }, { "Third": [ { "Forth": "Test21" }, { "Forth": "Test22" } ], "ID": "ID2" } ] } }

  1. Получение значения по заданному ключу.

    Путь: First

    Значение:

    { "Second": [ { "Third": [ { "Forth": "Test11" }, { "Forth": "Test12" } ], "ID": "ID1" }, { "Third": [ { "Forth": "Test21" }, { "Forth": "Test22" } ], "ID": "ID2" } ] }

  2. Получение значения по индексу.

    Путь: First.Second[1].Third[1].Forth

    Значение: Test22

  3. Получение все значенией расположенных в списке.

    Путь: First.Second[].Third[].Forth

    Результат выполнения:

    Путь по которому расположено значение
    Значение
    First.Second[0].Third[0].Forth Test11
    First.Second[0].Third[1].Forth Test12
    First.Second[1].Third[0].Forth Test21
    First.Second[1].Third[1].Forth Test22
  4. Обработка пути содержащего переход к родительскому элементу.

    1. First.Second[1].Third[1].Forth.^.^.^.ID

      Результат выполнения:

      Путь по которому расположено значение
      Значение
      First.Second[1].ID ID2
    2. First.Second[].Third[].Forth.^.^.^.ID

      Результат выполнения:

      Путь по которому расположено значение
      Значение
      First.Second[0].ID ID1
      First.Second[1].ID ID2

Использование синтаксического анализатора пути в storage-объекте

Пример использования анализатора.

IStoragePathParser parser = new StoragePathParser(); // Объект можно получить из Unity-контейнера по IStoragePathParser.

// Пример пути для объекта, расположенного в табличной секции карточки `Card`. string path1 = "Sections.KrStages.Rows[0].RuntimeSourceCondition";

// Пример пути для объекта, расположенного в строковой секции карточки `Card`. string path2= "Sections.KrSecondaryProcesses.Fields.VisibilitySourceCondition";

IReadOnlyList<IStoragePathItem> parseResult1 = parser.Parse(path); IReadOnlyList<IStoragePathItem> parseResult2 = parser.Parse(path);

Использование объекта, обеспечивающего выполнение действий с элементами storage-объекта

IStoragePathResolver предназначен для получения и присвоения значений по заданонму пути внутри storage-объекта.

IStoragePathParser parser = new StoragePathParser(); // Объект можно получить из Unity-контейнера по IStoragePathParser. IStoragePathResolver resolver = new StoragePathResolver(); // Объект можно получить из Unity-контейнера по IStoragePathResolver.

Card card = ...GetCard(); // Любой способ получения карточки

// Получаем storage от объекта Card (это может быть также любой объект типа, который реализует IStorageObjectProvider). IDictionary<string, object> storage = card.GetStorage();

// Путь в storage-объекте. string path = "Sections.KrStages.Rows[5].RuntimeSourceCondition";

// Анализ пути. IReadOnlyList<IStoragePathItem> pathParseResult = parser.Parse(path);

// Получение объекта, находящегося в хранилище по заданному пути. IList<(IReadOnlyList<IStoragePathItem> PathItems, object Value)> result = resolver.Resolve(pathParseResult, storage);

// Если необходимо по данному пути присвоить новый объект/значение, то необходимо использовать метод SetValueWithSuffix. object newValue = new () { Field1 = "someString" }; resolver.SetValueWithSuffix(pathParseResult, storage, newValue);

// Метод SetValueWithSuffix также позволяет, в случае необходимости, // добавить суффикс к ключу, по которому будет расположен объект. string suffix = "my-suffix";

// Если был указан суффикс, т.е. он не является значением null или пустой строкой, // то объект newValue, который до этого располагался по ключу "RuntimeSourceCondition" (это последний элемент пути), // будет сохранён по ключу "RuntimeSourceCondition::my-suffix", а ключ "RuntimeSourceCondition" будет удален из storage. resolver.SetValueWithSuffix(pathParseResult, storage, newValue, suffix);

Использование объекта, который позволяет запоминать и восстанавливать значения из хранилища (storage) по заданным путям.

IStorageValuesKeeper предназначен для того, чтобы запоминать и восстанавливать значения из хранилища по заданным путям.

StoragePathResolveOptions - опции в виде флагов для определения поведения при разрешении путей.

// Создание объекта StorageValuesKeeper. Такое создание объекта приведено для примера, рекомендуется получать объект из Unity-контейнера по интерфейсу IStorageValuesKeeper. IStorageValuesKeeper valuesKeeper = new StorageValuesKeeper(new StoragePathParser(), new StoragePathResolver());

// Для использования механизма сохранения/восстановления значений необходимо задать пути, по которым эти значения находятся. // Например, сохраним некоторые значения для карточки. var pathsForValuesKeeper = new List<StorageContentMapping> { // Значения карточки с прямыми путями. new() { StoragePath = "Card.Modified" },

// Если точка является не разделителем пути, а входит в состав значения части пути, ее (точку) необходимо экранировать символом '\'. new() { StoragePath = @"Info.\.importVersion" },

// Файлы карточки new() { // Т.к. файлов может быть несколько, в пути использован wildcard типа '[]'. StoragePath = "Card.Files[].Card.Version", // То, что используется wildcard, подразумевает, что по такому пути могут быть несколько значений, следовательно, чтобы их правильно разрешить в дальнейшем, // необходимо указать путь до уникального (для данной коллекции значений) идентификатора, с которыми значения будут сопоставлены. // Путь до идентификаторов указывается относительно пути до значений. IDKeys = new List<string> { "^.RowID" } // В данном случае запись означает, что путь до идентификаторов - "Card.Files[].RowID". },

// Общие данные сателлитов new() { StoragePath = @"Card.Info.\.satellites[].Modified", IDKeys = new List<string> { "ID" } // Путь до идентификаторов - "Card.Info.\.satellites[].ID" },

// Возможно использование нескольких wildcards. // Файлы сателлитов new() { // Если в пути имеются несколько wildсards типа [], то необходимо задать относительные пути до идентификаторов для каждого wildcard. // Пути до иентификаторов должны быть в строгом порядке, а именно, первыми должны быть заданы идентификаторы для конечных значений, которые должны быть сохранены, // в данном случае это коллекция где содержатся поля с ключем "Version", затем для родительских коллекций и так далее если количество wildcards больше. StoragePath = @"Card.Info.\.satellites[].Files[].Card.Version", IDKeys = new List<string> { "^.RowID", // Путь до идентификаторов, которые относятся непосредственно к полям с сохраняемым значением - "Card.Info.\.satellites[].Files[].RowID" "^.^.^.ID" // Путь до идентификаторов, которые относятся к родительским коллекциям - "Card.Info.\.satellites[].ID" } } };

// Запомнить нужные значения. Метод KeepValues принимает сам объект хранилища, коллекцию путей до значений и опции в виде флагов. valuesKeeper.KeepValues( storage, pathsForValuesKeeper, // В этом примере опции указывают на то, что при обработке списков внутри хранилища (например, в той части пути, которая содержит wildcard типа []), // если такой список равен `null`, не будет сенерировано исключение, а значением по такому пути будет являться `null`. StoragePathResolveOptions.IgnoredNullList);

/* Логика после которой необходимо восстановить запомненные значения. */ ...

// Восстановить запомненные значения. // Если значения были запомнены по путям с использованием wildcards и указанием относительных путей до идентификаторов, то такие значения будут восстановлены // с учетом этих идентификаторов. Иначе значения будут восстановлены по прямым путям. // Параметр ignoreNotFound означает, что не требуется генерировать исключение в случае невозможности разрешения пути в переданном хранилище при попытке восстановить значение. valuesKeeper.RestoreValues(storage, ignoreNotFound: true);

Note

Допустимо, что передаваемый в метод RestoreValues() объект хранилища может являться объектом, отличным от того, из которого значения были запомнены в методе KeepValues().

Back to top