Get Multiple Connection Strings in appsettings.jso

2020-03-18 07:18发布

问题:

Just starting playing with the .Net Core RC2 by migrating a current MVC .Net app I developed. It looks like to me because of the way that configuration is handled with appsettings.json that if I have multiple connection strings I either have to use EF to retrieve a connectionstring or I have to create separate classes named for each connection string. All the examples I see either use EF (which doesn't make sense for me since I will be using Dapper) or the example builds a class named after the section in the config. Am I missing a better solution?

    "Data": {
        "Server1": {
          "ConnectionString": "data source={server1};initial catalog=master;integrated security=True;"
        },
        "Server2": {
          "ConnectionString": "data source={server2};initial catalog=master;integrated security=True;"
        }
    }

Why would I want to build two classes, one named "Server1" and another "Server2" if the only property each had was a connectionstring?

回答1:

There are a couple of corrections that I made to Adem's response to work with RC2, so I figured I better post them.

I configured the appsettings.json and created a class like Adem's

{
    "ConnectionStrings": {
      "DefaultConnectionString": "Default",
      "CustomConnectionString": "Custom"
    }
}

and

public class ConnectionStrings
{
    public string DefaultConnectionString { get; set; }

    public string CustomConnectionString { get; set; }
}

most of Adem's code comes out of the box in VS for RC2, so I just added the line below to the ConfigureServices method

services.Configure<Models.ConnectionStrings>(Configuration.GetSection("ConnectionStrings"));

The main missing point is that the connection string has to be passed to the controller (Once you’ve specified a strongly-typed configuration object and added it to the services collection, you can request it from any Controller or Action method by requesting an instance of IOptions, https://docs.asp.net/en/latest/mvc/controllers/dependency-injection.html)

So this goes to the controller,

private readonly ConnectionStrings _connectionStrings;
        public HomeController(IOptions<ConnectionStrings> connectionStrings)
        {
            _connectionStrings = connectionStrings.Value;
        }

and then when you instantiate the DAL you pass the appropriate connectionString

DAL.DataMethods dm = new DAL.DataMethods(_connectionStrings.CustomConnectionString);

All the examples show this, they just don't state it, why my attempts to pull directly from the DAL didn't work



回答2:

You can use Options to access in DAL layer. I will try to write simple example(RC1):

First you need to create appsettings.json file with below content:

{
    "ConnectionStrings": {
      "DefaultConnectionString": "Default",
      "CustomConnectionString": "Custom"
    }
}

Then create a class:

public class ConnectionStrings
{
    public string DefaultConnectionString { get; set; }

    public string CustomConnectionString { get; set; }
}

And in Startup.cs

    private IConfiguration Configuration;
    public Startup(IApplicationEnvironment app)
    {
        var builder = new ConfigurationBuilder()
           .SetBasePath(app.ApplicationBasePath)
           .AddJsonFile("appsettings.json");

        Configuration = builder.Build();
    }
    public void ConfigureServices(IServiceCollection services)
    {
        // ....
        services.AddOptions();
        services.Configure<ConnectionStrings>(Configuration.GetSection("ConnectionStrings"));
    }

Finally inject it in the DAL class:

    private IOptions<ConnectionStrings> _connectionStrings;
    public DalClass(IOptions<ConnectionStrings> connectionStrings)
    {
        _connectionStrings = connectionStrings;
    }
    //use it


回答3:

I don't like the idea of instantiating the DAL. Rather, I'd do something like this

public class ConnectionStrings : Dictionary<string, string> { }

And something like this in the ctor of the DAL

public Dal(IOptionsMonitor<ConnectionStrings> optionsAccessor, ILogger<Dal> logger)
{
      _connections = optionsAccessor.CurrentValue;
      _logger = logger;
}

Now you have all the connection strings in the DAL object. You can use them on each query or even select it by index on every call.