Uses of Configuration Provider and Options Pattern in ASP.NET Core
Application overview
In ASP.NET core, we often use application settings from different configuration files and load to a some files. Application settings can be in the appsettings.json or docker-compose.yml or .env or any other configuration file. We can use IOptions
Tools and Technology used The following tools and technologies has been used for this application
- Visual Studio 2019
- Visual C#
- ASP.NET Core Web API
- .NET Framework 5.0
Step 1: Create a asp.net core web api project
- Create a new project using visual studio 2019
- Choose the C# ASP.NET Web API (.NET Core) project template
- Create a web api project name - “Catalog.API”
Step 2: Add docker and docker compose file
- Click right button on project -> Add Docker Support -> Linux
- Click right button on project -> Container Orchestrator Support -> Linux
Step 3: Modify appsettings.json
- Modify appsettings.json as follows
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=CatalogDB;Trusted_Connection=True;MultipleActiveResultSets=true",
"ServiceName" : "Catalog.API",
//"Server": "LocalSQLServer",
"Port": 112233,
"DatabaseSettings": {
"Server": "localhost",
"Provider": "SQL Server",
"Database": "DemoDb",
"Port": 1234,
"UserName": "sa",
"Password": "mahedee123"
},
"AllowedHosts": "*"
}
Step 4: Add .env file in the root directory
- Add .env file int root directory and modify as follows
# PORT = 4444
CONFIG_STORAGE_CATALOG_URL=http://host.docker.internal:5202/c/api/v1/catalog/items/[0]/pic/
NAME = Md. Mahedee Hasan
DBNAME = ContainerDB
PORT = 4545
#AZURE_CATALOG_DB=<YourAzureSQLDBCatalogDBConnString>
Step 5: Modify docker-compose.override.yml
- Modify docker-compose.override.yml as follows
version: '3.4'
services:
catalog.api:
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=https://+:443;http://+:80
- ConnectionString=${AZURE_CATALOG_DB:-Server=sqldata;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word}
- PATH_BASE=/catalog-api
- PicBaseUrl=${CONFIG_STORAGE_CATALOG_URL}
- Name=${NAME}
#- DbName=${DBNAME}
- Port=${PORT}
ports:
- "80"
- "443"
volumes:
- ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro
- ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro
Step 6: Add DatabaseSettings and CatalogSettings model class
DatabaseSettings
namespace Catalog.API
{
public class DatabaseSettings
{
public string Server { get; set; }
public string Provider { get; set; }
public string Database { get; set; }
public int Port { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
}
}
CatalogSettings.cs
namespace Catalog.API
{
public class CatalogSettings
{
public string ConnectionString { get; set; }
public string ServiceName { get; set; }
public string PicBaseUrl { get; set; }
public string PATH_BASE { get; set; }
public DatabaseSettings DatabaseSettings { get; set; }
}
}
Step 7: Modify Program class
Program.cs
using Catalog.API;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.IO;
// Using top-level programming
Console.WriteLine("Entering into Main method ... ");
var configuration = GetConfiguration();
IConfiguration GetConfiguration()
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables();
return builder.Build();
}
try
{
Console.WriteLine("Configuring web host {0}...", Program.AppName);
var host = CreateHostBuilder(configuration, args);
host.Run();
return 0;
}
catch (Exception exp)
{
return 1;
}
finally
{
//finally block
}
IWebHost CreateHostBuilder(IConfiguration configuration, string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration(x => x.AddConfiguration(configuration))
.CaptureStartupErrors(false)
.UseStartup<Startup>()
.Build();
public static class Program
{
public static string Namespace = typeof(Startup).Namespace;
public static string AppName = Namespace.Substring(Namespace.LastIndexOf('.', Namespace.LastIndexOf('.') - 1) + 1);
}
8. Modify Startup class
Starup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
namespace Catalog.API
{
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.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
// Use option pattern
services.Configure<CatalogSettings>(Configuration);
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Catalog.API", Version = "v1" });
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// Debug and Check some configuration
var pathBase = Configuration["PATH_BASE"];
var picBaseURL = Configuration["PicBaseUrl"];
var name = Configuration["name"];
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Catalog.API v1"));
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
Step 9: Create a Controller class for testing
- Create Controller name CatalogController as follows CatalogController.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
namespace Catalog.API.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class CatalogController : ControllerBase
{
private CatalogSettings _settings;
public CatalogController(IOptions<CatalogSettings> settings)
{
_settings = settings.Value;
}
// GET: api/<CatalogController>
[HttpGet]
public CatalogSettings Get()
{
return _settings;
}
}
}
Step 10: Build and run the application Now build and run the application. You will see the swagger ui and test CatalogController to test settings.