0

I have a new Asp.Net core application that has the following entry in the appsettings.json file:

{
  "DatabaseConnections": {
    "DatabaseUri": "https://localhost:8081",
    "ApplicationKey": "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==",
    "DatabaseName": "MyDatabase"
  }
}

I'm attempting to pull the data out to use during the ConfigureServices method, using the .Bind method:

public class DatabaseConnections
{
    public string DatabaseUri { get; set; }

    public string ApplicationKey { get; set; }

    public string DatabaseName { get; set; }
}

private DatabaseConnections databaseSettings;

private DatabaseConnections DatabaseSettings
{
    get
    {
        if (databaseSettings == null)
        {
            databaseSettings = new DatabaseConnections();
            Configuration.Bind(databaseSettings);
        }

        return databaseSettings;
    }
}

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IDocumentClient>(
        new DocumentClient(
            new Uri(DatabaseSettings.DatabaseUri),
            DatabaseSettings.ApplicationKey));
}

However, when I perform the binding, the settings are all set to null. But if I try to do it without the model binding, it seems to work fine:

public void ConfigureServices(IServiceCollection services)
{
    var databaseSettings = Configuration.GetSection("DatabaseConnections");

    services.AddSingleton<IDocumentClient>(
        new DocumentClient(
            new Uri(databaseSettings.GetValue<string>("DatabaseUri")),
            databaseSettings.GetValue<string>("ApplicationKey")));
}

What am I doing wrong?

user247702
  • 23,641
  • 15
  • 110
  • 157
Obsidian Phoenix
  • 4,083
  • 1
  • 22
  • 60

2 Answers2

1

You can either build a service provider or use string.

Configuration.GetSection("DatabaseConnections:DatabaseUri").Value

For example,

public void ConfigureServices(IServiceCollection services)
{
    services.AddOptions();
    services.Configure<DatabaseConnections>(
        Configuration.GetSection("DatabaseConnections"));


    var sp = services.BuildServiceProvider();
    var databaseConnections = sp.GetService<IOptions<DatabaseConnections>>();

    services.AddSingleton<IDocumentClient>(
        new DocumentClient(new Uri(databaseConnections.Value.DatabaseUri)),
        databaseConnections.Value.ApplicationKey));
}

Controller

public class HomeController : Controller
{
    private readonly DatabaseConnections _databaseConnections;

    public HomeController(IOptions<DatabaseConnections> databaseConnections)
    {
        _databaseConnections = databaseConnections.Value;
    }
}
Win
  • 61,100
  • 13
  • 102
  • 181
  • At the risk of an XY situation: the reason I wanted to put it into the class during startup was so I could pass it to a config class without using magic strings. Will it just not bind during the startup execution? – Obsidian Phoenix Jun 27 '17 at 18:45
0

The other answer is good if you want to use IOptions, for whatever reason I really don't like doing it and prefer binding to a class.

You can do this with a single line in your Configure Services method :

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton(Configuration.GetSection("DatabaseConnections").Get<DatabaseConnections>());
}

It looks like you are missing the "Get" on the end which takes the configuration section and binds it to your class.

Further info : http://dotnetcoretutorials.com/2016/12/26/custom-configuration-sections-asp-net-core/

MindingData
  • 11,924
  • 6
  • 49
  • 68