SteinTech
SteinTech

Reputation: 4068

Having issues reading and loading config into custom objects in asp.net core

Im trying to read the config and populate the custom objects, but I only get LCTools but not LCLog.

I've tried to use .GetSection("LCTools:LCLog")

appsettings.json:

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

Where I read and load config:

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;
}

Classes:

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;
}

Upvotes: 2

Views: 307

Answers (1)

Set
Set

Reputation: 49779

Your main problem looks like a misunderstanding of how config builder populates option classes. Configuration API while reading all config sources, internally populates a collection of key-values (simply Dictionary<string, string>), where a key is a config param name with : used as a delimiter). For your json file that dictionary contains one item {"LCTools:LCLog:AppId": "1"}

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

The above code means to configuration builder the following: use from dictionary only items with key started from LCTools:LCLog, take all available configs and map them to public properties of _LCToolsOptions class using remaining key part for mapping.

Configuration builder doesn't do data deserialization. Instead, it constructs option class using default constructor without any parameters and then tries to set public properties for that class using taken key-values from the specified config path.

And you have nothing as result cause your LCTools:LCLog section has AppId key-value, but _LCToolsOptions class doesn't provide AppId public property.


If you want to construct option class from data in LCTools:LCLog section, you should build the LCLogOptions instance from .GetSection("LCLog") section:

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

as properties like AppId are defined in LCLogOptions.


If you want to build an instance of _LCToolsOptions, then you need to modify your option class to:

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

note, that type need to be changed from interface to specific class, and property name (LCLog) should reflect the name used in JSON config file.

and then do

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

Upvotes: 1

Related Questions