AliReza Beigy
AliReza Beigy

Reputation: 629

Map appsettings.json to class

I'm trying to convert appsettings.json to C# class

I use Microsoft.Extensions.Configuration to read the configuration from appsettings.json

I write the following code using reflection but I'm looking for a better solution

foreach (var (key, value) in configuration.AsEnumerable())
{
    var property = Settings.GetType().GetProperty(key);
    if (property == null) continue;
    
    object obj = value;
    if (property.PropertyType.FullName == typeof(int).FullName)
        obj = int.Parse(value);
    if (property.PropertyType.FullName == typeof(long).FullName)
        obj = long.Parse(value);
    property.SetValue(Settings, obj);
}

Upvotes: 14

Views: 17565

Answers (4)

Shervin Ivari
Shervin Ivari

Reputation: 2501

Don't reinvent the wheel! As some users have mentioned, try using the Options pattern which is provided by Microsoft.

Here is a simple example of how to do it:

appsetting.json

{
  "AppSettings": {
    "Setting1": "Value1",
    "Setting2": "Value2"
  }
}

AppOptions.cs

public class AppOptions
{
    public string Setting1 { get; set; }
    public string Setting2 { get; set; }
}

Configure it with dependency injection

services.Configure<AppOptions>(Configuration.GetSection("AppSettings"));

This is the way you inject it into service, I use IOptions, and I highly suggest checking other Options interfaces such as IOptionsSnapshot based on your case.

public SomeService(IOptions<AppOptions> appOptions)
{
    _appOptions = appOptions.Value;
}

Upvotes: 1

Kieran Foot
Kieran Foot

Reputation: 745

I'm shocked nobody has suggested using the IOptions pattern or even asked if this a system involving DI (Dependency Injection). If the system is indeed using DI, I would suggest using the IOptions pattern described here Options Pattern as it not only allows for the options to be injected where they're needed, but also allows for change notifications so you can receive configuration changes and act on them.

Upvotes: 3

Karney.
Karney.

Reputation: 5031

You can use Dictionary to get the json, and then use JsonSerializer to convert the json.

public IActionResult get()
    {
        Dictionary<string, object> settings = configuration
        .GetSection("Settings")
        .Get<Dictionary<string, object>>();
        string json = System.Text.Json.JsonSerializer.Serialize(settings);

        var setting = System.Text.Json.JsonSerializer.Deserialize<Settings>(json);

        return Ok();
    }

Here is the model

public class Settings
{
    public string property1 { get; set; }
    public string property2 { get; set; }
}

In appsettings.json

 "Settings": {
  "property1": "ap1",
  "property2": "ap2"
 },

enter image description here

Upvotes: 4

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236218

Build configuration from appsettings.json file:

var config = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json", optional = false)
            .Build()

Then add Microsoft.Extensions.Configuration.Binder nuget package. And you will have extensions to bind configuration (or configuration section) to the existing or new object.

E.g. you have a settings class (btw by convention it's called options)

public class Settings
{
    public string Foo { get; set; }
    public int Bar { get; set; }
}

And appsettings.json

{
  "Foo": "Bob",
  "Bar": 42
}

To bind configuration to new object you can use Get<T>() extension method:

var settings = config.Get<Settings>();

To bind to existing object you can use Bind(obj):

var settings = new Settings();
config.Bind(settings);

Upvotes: 23

Related Questions