I'm starting with an asp.net core 2.0 mvc web and I can not read directly from a class the value of the appsettings.json (ConnectionString) that I need.
I've found a lot of documentation, although none of them gets what I want. Summing up all the documentation that I have read, what the majority proposes is the following:
One of the many examples I found: link
The problem I have is that I am structuring the code in three layers (interface, business logic and data access) that call each other respectively and I do not see how to get to the access layer. data the connection string without having to send it by parameter through the different layers.
Right now the idea that I have in my head is to be able to read from the data access class the values of the appsettings.json, although if someone knows another better way to do it I would also like to know.
Thanks in advance.
Edit1:
AppSettings.cs
Class that I created to store appsettings.json data
public class AppSettings
{
public Connection Connection { get; set; }
}
public class Connection
{
public string ConnectionString { get; set; }
}
Startup.cs
I understand that here the "AppSettings" class is added to the service container.
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddOptions();
// Add appSettings
services.Configure<AppSettings>(settings =>
{
settings.Connection = new Connection()
{
ConnectionString = Configuration["Data:DefaultConnection:ConnectionString"]
};
});
services.AddSingleton<IConfiguration>(Configuration);
}
DataAccess.cs
Data access layer. Where I should be able to access AppSettings.
private readonly AppSettings _settings;
public DataAccess(IOptions<AppSettings> settings)
{
_settings = settings.Value;
}
BusinessLogic.cs
Business layer, where I instantiate the data access layer. It generates a compilation error because there are missing parameters to send to the constructor, which seems logical to me. Maybe I can not understand the injection of dependencies very well.
public Business()
{
Data = new DataAccess();
}
Edit2: This is how I have solved it, in case someone is good for something
Startup.cs
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
// Add framework services
services.AddMvc();
// Configure AppSettings
services.Configure<AppSettings>(settings =>
{
settings.Data = new Data()
{
ConnectionString = Configuration["Data:ConnectionString"].ToString()
};
});
// Configure BusinessLogic
services.AddSingleton<IBusinessLogic, BusinessLogic>();
// Configure DataAccess
services.AddSingleton<IDataAccess, DataAccess>();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env) ...
}
DataAccess.cs
public class DataAccess : IDataAccess
{
private readonly AppSettings _settings;
public DataAccess(IOptions<AppSettings> settings)
{
_settings = settings.Value;
}
public string GetConnectionString()
{
return _settings.Data.ConnectionString;
}
}
In the data access layer I create a test method that returns the connection string.
BusinessLogic.cs
public class BusinessLogic : IBusinessLogic
{
private readonly IDataAccess _data;
public BusinessLogic(IDataAccess data)
{
_data = data;
}
public string GetConnectionString()
{
return _data.GetConnectionString();
}
}
In the business layer I create another test method that returns the connection string. This in turn gets it from the data layer.
HomeController.cs
public class HomeController : Controller
{
private readonly IBusinessLogic _businness;
public HomeController(IBusinessLogic business)
{
_businness = business;
}
public IActionResult Index()
{
return View(new HomeModel(_businness.GetConnectionString()));
}
}
In the Home view controller, I paint the chain of connection obtained from the business layer.