Проблемы с чтением и загрузкой конфигурации в пользовательские объекты в ядре asp.net - PullRequest
0 голосов
/ 28 апреля 2018

Я пытаюсь прочитать конфигурацию и заполнить пользовательские объекты, но я получаю только LCTools , но не LCLog .

Я пытался использовать .GetSection("LCTools:LCLog")

appsettings.json :

{   
  "LCTools": {
    "LCLog": {
      "AppId": 1
    }   
  }
}

Где я читаю и загружаю конфигурацию :

public static IApplicationBuilder UseLCLog(this IApplicationBuilder builder, IConfiguration configuration)
{
    ILCToolsOptions options = configuration.GetSection("LCTools").GetSection("LCLog").Get<_LCToolsOptions>();
    LogManager.Configuration = LCLog.Utility.GetConfiguration(options);
    ILoggerFactory factory = builder.ApplicationServices.GetRequiredService<ILoggerFactory>();

    factory.AddNLog();
    factory.AddProvider(new DbLCLogProvider(options.LCLogOptions.Filter, configuration));           

    return builder;
}

Классы :

public interface ILCLogBase
{
    Func<string, LogLevel, bool> Filter { get; set; }
}

public abstract class LCLogBase : ILCLogBase
{
    public Func<string, LogLevel, bool> Filter { get; set; }
}

public interface ILCToolsOptions
{
    ILCLogOptions LCLogOptions { get; set; }
}

public class _LCToolsOptions : LCLogBase, ILCToolsOptions
{
    public ILCLogOptions LCLogOptions { get; set; }
}

public interface ILCLogOptions : ILCLogBase
{
    int AppId { get; set; }
    string FileName { get; set; }
    string FileLogLevel { get; set; }
    string DbLogLevel { get; set; }
    string MicrosoftLevel { get; set; }
    string ConnectionString { get; set; }
}

public class LCLogOptions : LCLogBase, ILCLogOptions
{
    public int AppId { get; set; }
    public string FileName { get; set; } = "${basedir}/_Log/${shortdate}.log";
    public string FileLogLevel { get; set; } = "Trace";
    public string DbLogLevel { get; set; } = "Warn";
    public string MicrosoftLevel { get; set; } = "Trace";
    public string ConnectionString { get; set; } = Utility.ConnectionString;
}

1 Ответ

0 голосов
/ 28 апреля 2018

Ваша основная проблема выглядит как неправильное понимание того, как конструктор конфигураций заполняет классы опций. API-интерфейс конфигурации при чтении всех источников конфигурации внутренне заполняет коллекцию значений ключей (просто Dictionary<string, string>), где ключ - это имя параметра конфигурации с :, используемым в качестве разделителя). Для вашего файла JSON этот словарь содержит один элемент {"LCTools:LCLog:AppId": "1"}

configuration.GetSection("LCTools").GetSection("LCLog").Get<_LCToolsOptions>();

Приведенный выше код означает для построителя конфигурации следующее: использовать из словаря только элементы с ключом, начинающимся с LCTools:LCLog, взять все доступные конфигурации и сопоставить их с общими свойствами класса _LCToolsOptions, используя оставшуюся часть ключа для сопоставления.

Конструктор конфигурации не выполняет десериализацию данных. Вместо этого он создает класс параметров с использованием конструктора по умолчанию без каких-либо параметров, а затем пытается установить открытые свойства для этого класса, используя взятые значения ключей из указанного пути конфигурации.

И у вас ничего не получится, потому что в разделе LCTools:LCLog есть ключ-значение AppId, но класс _LCToolsOptions не предоставляет AppId открытое свойство.


Если вы хотите построить класс опций из данных в секции LCTools:LCLog, вы должны построить экземпляр LCLogOptions из секции .GetSection("LCLog"):

    var options = configuration.GetSection("LCTools")
                               .GetSection("LCLog")
                               .Get<LCLogOptions>();

как свойства типа AppId определены в LCLogOptions.


Если вы хотите создать экземпляр _LCToolsOptions, вам нужно изменить класс параметров на:

public class _LCToolsOptions : LCLogBase, ILCToolsOptions
{
    public ILCLogOptions LCLog { get; set; }
    // instead of
    // public ILCLogOptions LCLogOptions { get; set; }
}

обратите внимание, что тип должен быть изменен с интерфейса на определенный класс, а имя свойства (LCLog) должно отражать имя, используемое в файле конфигурации JSON.

, а затем сделать

var options = configuration.GetSection("LCTools").Get<_LCToolsOptions>();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...