Как получить доступ к значению ключа, который является родительским для других ключей, используя объект IConfiguration?

#c# #asp.net-core #configuration

#c# #asp.net-core #конфигурация

Вопрос:

У меня есть файл конфигурации json ниже:

 {
    "key1": false,
    "key2": "hello world",
    "key3": {
        "f1_somekey": true,
        "f2_somekey": true,
        "f3_cachekey": [
            {
                "s": 1,
                "p": [4, 6, 7, 8, 9]
            },
            {
                "s": 2,
                "p": [5]
            },
            {
                "p": [10, 11, 12, 13, 14]
            }
        ]
    }
}
  

Я пытаюсь получить значение каждого из ключей из объекта IConfiguration, но я не понимаю, как получить значение f3_cachekey ? Все остальные значения ключей я могу извлечь, но запутать f3_cachekey .

 var key1Value = Configuration["key1"];
var key2Value = Configuration["key2"];
var key3_f1Value = Configuration["key3:f1_somekey"];
var key3_f2Value = Configuration["key3:f2_somekey"];
  

Мне нужно создать словарь целых чисел в качестве key и HashSet целых чисел в качестве value for f3_cachekey .

 Dictionary<int, HashSet<int>> sToPMapping = new Dictionary<int, HashSet<int>>();
  

У меня есть два случая в f3_cachekey :

  • У меня есть комбинация s и массив p's . В приведенном выше примере — первый и второй объекты json f3_cachekey .
  • Во-вторых, у меня просто есть массив p's , который является третьим объектом json. Для этого случая у меня есть несколько предопределенных s , уже сохраненных в другом HashSet , которые я буду использовать в качестве ключа, и каждое их s значение будет всем этим p's .

Возможно ли это сделать? Также, если f3_cachekey его нет в приведенном выше json, мне нужно создать пустой объект словаря.

Ответ №1:

Настройка с помощью Microsoft.Расширения.Конфигурация на самом деле представляет собой плоское сопоставление ключ-значение. Это просто источник конфигурации JSON, который позволяет вам указывать конфигурацию в виде иерархии. Однако после загрузки файла иерархия сглаживается до прямого сопоставления ключа со значением, где ключом является путь конфигурации.

Для вашего конкретного примера JSON из конфигурации доступны следующие сопоставления:

 key1                     => false
key2                     => hello 
key3:f1_somekey          => true
key3:f2_somekey          => true
key3:f3_cachekey:0:s     => 1
key3:f3_cachekey:0:p:0   => 4
key3:f3_cachekey:0:p:1   => 6
key3:f3_cachekey:0:p:2   => 7
key3:f3_cachekey:0:p:3   => 8
key3:f3_cachekey:0:p:4   => 9
key3:f3_cachekey:1:s     => 2
key3:f3_cachekey:1:p:0   => 5
key3:f3_cachekey:2:p:0   => 10
key3:f3_cachekey:2:p:1   => 11
key3:f3_cachekey:2:p:2   => 12
key3:f3_cachekey:2:p:3   => 13
key3:f3_cachekey:2:p:4   => 14
  

Как вы, надеюсь, можете видеть из этого, в объекте конфигурации нет массивов или объектов. Это просто путь, в котором : разделяются разделы и одно значение. Значения массива идентифицируются по индексу массива в пути, например f3_cachekey:0 , для первого элемента.

Эта структура позволяет очень просто поддерживать различные источники конфигурации, поскольку все они могут создавать такое сопоставление ключ-значение, даже такие простые вещи, как переменные среды. Но эта структура также немного затрудняет использование конфигурации для нетривиальных значений. По этой причине в структуре конфигурации есть связующая часть.

Если вы внимательно посмотрите на приведенный выше список, вы увидите, что в нем нет key3:f3_cachekey записи, а также нет key3:f3_cachekey:0 key3:f3_cachekey:0:p записей или. Это потому, что в этих ключах есть не само значение, а скорее что-то другое вложенная структура, объект или массив. В рамках конфигурации они известны как разделы, которые в основном являются просто способом рассказать о подмножестве пути. Например, раздел с ключом key3:f3_cachekey:0 выглядит так:

 s     => 1
p:0   => 4
p:1   => 6
p:2   => 7
p:3   => 8
p:4   => 9
  

Вы можете привязывать целые конфигурации или разделы конфигурации к типизированным объектам, например, массивам и спискам или даже вложенным объектам C #. Это часто используется при объединении конфигурации с шаблоном параметров. Вы также можете вызвать процесс привязки вручную:

С приведенной выше конфигурацией вы могли бы, например, получить доступ к массиву at key3:f3_cachekey:0:p , получив раздел конфигурации по этому пути и привязав его к массиву int:

 int[] values = configuration.GetSection("key3:f3_cachekey:0:p").Get<int[]>();
  

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

 CacheKeySP[] values = configuration.GetSection("key3:f3_cachekey").Get<CacheKeySP[]>();
  

Это предполагает определение класса следующим образом:

 public class CacheKeySP
{
    public int S { get; set; }
    public int[] P { get; set; }
}
  

Комментарии:

1. Я вижу. Теперь я понял, как это работает. Есть ли какой-нибудь способ создать словарь так, как я пытался, с помощью этой текущей структуры json для f3_cachekey объекта с использованием конфигурации? или мне нужно немного изменить структуру json, чтобы сделать именно то, что я пытался сделать? По сути, я хочу создать словарь для f3_cachekey объекта.

2. У меня есть только эти два случая для f3_cachekey объекта. Либо комбинация s и p , либо просто массив p's .

3. Я бы рекомендовал вам определить простой, но правильный тип для этого, т.Е. class SP { public int S { get; set; } public int[] P { get; set; } } . И затем вы можете привязать f3_cachekey к a SP[] .

4. хммм, я немного запутался в том, как я это заполню? Как вы думаете, вы можете привести пример, который поможет мне понять на этой основе мой код?

5. @user1950349 Я скорректировал свой последний пример, чтобы показать вам рабочий пример. Надеюсь, это поможет!