Когда я создаю свой корень конфигурации и делаю что-то вроде config["someSetting:subSettings"], он возвращает null, а фактические доступные настройки выглядят примерно так:
config["someSettings:subSettings:0"]
Есть ли лучший способ получить содержимое someSettings:subSettings в виде списка?
Может быть, это работает .. weblog.west-wind.com/posts/2016/may/23/ Venky 26.08.2016
Может быть. Я использую консольное приложение, которое не является asp.net, но я посмотрю, смогу ли я получить коллекцию сервисов. devlife 26.08.2016
Да, это работает и в консольных приложениях. Ничего особенного в asp.net Victor Hurdugaci 26.08.2016
Я спрашиваю только потому, что получаю следующее: Could not load file or assembly 'Microsoft.Extensions.Configuration.Binder, Version=1.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. The system cannot find the file specified devlife 29.08.2016
Вы также можете использовать класс DTO для анализа конфигурации VMAtm 03.10.2017
Ответы
Ответ 1 · рейтинг 48 · Victor Hurdugaci
Вы можете использовать связыватель конфигурации, чтобы получить строгое представление источников конфигурации.
Это пример из теста, который я написал ранее, надеюсь, он поможет:
[Fact]
public void BindList()
{
var input = new Dictionary<string, string>
{
{"StringList:0", "val0"},
{"StringList:1", "val1"},
{"StringList:2", "val2"},
{"StringList:x", "valx"}
};
var configurationBuilder = new ConfigurationBuilder();
configurationBuilder.AddInMemoryCollection(input);
var config = configurationBuilder.Build();
var list = new List<string>();
config.GetSection("StringList").Bind(list);
Assert.Equal(4, list.Count);
Assert.Equal("val0", list[0]);
Assert.Equal("val1", list[1]);
Assert.Equal("val2", list[2]);
Assert.Equal("valx", list[3]);
}
Важная часть - это звонок Bind.
Тест и другие примеры находятся на
Ответ 2 · рейтинг 169 · Kirill Rakhman
Предположим, ваш appsettings.json выглядит так:
{
"foo": {
"bar": [
"1",
"2",
"3"
]
}
}
Вы можете извлечь элементы списка следующим образом:
Примечание: если вам нужно немедленно получить доступ к вашему списку в методе ConfigureServices, вы можете использовать ...
var subSettings = Configuration.GetSection("IDP").Get<List<IDP>>();
Тогда в вашем контроллере что-то вроде этого:
Public class AccountController: Controller
{
private readonly IOptions<List<IDP>> _IDPs;
public AccountController(IOptions<List<Defined>> IDPs)
{
_IDPs = IDPs;
}
...
}
просто в качестве примера я использовал его в другом месте в указанном выше контроллере следующим образом:
_IDPs.Value.ForEach(x => {
// do something with x
});
Edge Case
В случае, если вам нужно несколько конфигураций, но они не могут быть в массиве, и вы не знаете, сколько подпараметров у вас будет одновременно. Используйте следующий метод.
public class IDP
{
public String Description { get; set; }
public String IDPServer { get; set; }
public String IDPClient { get; set; }
public String Format { get; set; }
public String Instance { get; set; }
public String ClientId { get; set; }
public String Domain { get; set; }
public String TenantId { get; set; }
}
Создать расширение для объекта Expando
public static class ExpandObjectExtension
{
public static TObject ToObject<TObject>(this IDictionary<string, object> someSource, BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public)
where TObject : class, new()
{
Contract.Requires(someSource != null);
TObject targetObject = new TObject();
Type targetObjectType = typeof(TObject);
// Go through all bound target object type properties...
foreach (PropertyInfo property in
targetObjectType.GetProperties(bindingFlags))
{
// ...and check that both the target type property name and its type matches
// its counterpart in the ExpandoObject
if (someSource.ContainsKey(property.Name)
&& property.PropertyType == someSource[property.Name].GetType())
{
property.SetValue(targetObject, someSource[property.Name]);
}
}
return targetObject;
}
}
ConfigureServices
var subSettings = Configuration.GetSection("IDP").Get<List<ExpandoObject>>();
var idx = 0;
foreach (var pair in subSettings)
{
IDP scheme = ((ExpandoObject)pair).ToObject<IDP>();
if (scheme.Format == "AzureAD")
{
// this is why I couldn't use an array, AddProtecedWebApi requires a path to a config section
var section = $"IDP:{idx.ToString()}";
services.AddProtectedWebApi(Configuration, section, scheme.Description);
// ... do more stuff
}
idx++;
}
Ответ 4 · рейтинг 7 · Marc S
var settingsSection = config.GetSection["someSettings:subSettings"];
var subSettings = new List<string>;
foreach (var section in settingsSection.GetChildren())
{
subSettings.Add(section.Value);
}
Это должно дать вам необходимые значения, хранящиеся в subSettings
Приносим извинения за то, что подняли полустарую ветку. Мне было трудно найти ответ, так как многие методы устарели, например Get и GetValue. Это должно быть хорошо, если вам нужно только простое решение без привязки конфигурации. :)
Но ... помните, что если в классе настроек для этого списка установлены значения по умолчанию ... что настройки конфигурации будут добавочными и, следовательно, не будут перезаписывать исходные значения.
Таким образом, эти значения по умолчанию останутся, и вы не сможете удалить их с помощью каких-либо дополнительных настроек.
Кроме того, если вы также включили поставщик файлов Ini, может быть полезно знать, что для указания списка там ключи не имеют особого значения, если они уникальны, поэтому имеет смысл сохранить ключ и значения там то же самое, чтобы оказаться в списке.