Home > Net >  ASP.NET Core - Create a singleton class to supply connection string across the application
ASP.NET Core - Create a singleton class to supply connection string across the application

Time:10-28

I'm creating a ASP.NET Core Web API using ADO.NET (without Entity Framework). I need a singleton class to supply connection string to all the controllers.
I have done the following.

  • Defined a class DBUtils to have just one public property DBConnectionString.
  • Try to register the class as a singleton in startup.cs.
  • Use the class through DI in each controller to access the connection string.

   public class DBUtils
    {
        public string DBConnectionString { get; set; }

        public DBUtils(string connectionString)
        {
            this.DBConnectionString = connectionString;
        }
    }


 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.AddSingleton<DBUtils>();
            services.AddControllers();
        }
    }


public class CommonController : ControllerBase
{
    private string conStr;

    public CommonController(DBUtils utils)
    {
        conStr = utils.DBConnectionString;
    }

    public IActionResult GetData() {
        SqlConnection connection = new SqlConnection(conStr);
        //Get dat from the database
        return null;
    }
}

Now the problem is I'm not able to pass the connection string to the DBUtils constructor. I read from other posts that we should not use parameters to Singleton classes. But my class will only have one parameter and it will never change during execution. It gets the connection string from config file.

please help how to I pass connection string to my controllers. I don't want to use IConfiguration as DI in the controller class directly.


UPDATE: I realised that Singleton is not the approach for my requirement and as @Ceemah Four suggested we should use Options Pattern. Thanks

CodePudding user response:

This scenario has already been catered for in dotnet core. You do not need to create the DBUtils class. Neither do you need to set up the Singleton DI etc.

Assuming this is your appsettings.json

  "ConnectionStrings": {
    "SqlDatabase":  "connection string here"
  }

There are two potential approaches:

  1. Inject IConfiguration in Controller constructor - you can simply access the connection string value from the injected Configuration.
    public class CommonController : ControllerBase
    {
        private readonly IConfiguration _config;
        private string conStr;

        public CommonController(IConfiguration config)
        {
            _config = config;
        }

        public IActionResult GetData()
        {
            SqlConnection connection = new SqlConnection(_config.GetConnectionString("SqlDatabase"));
            //Get data from the database
            return null;
        }
    }
  1. Create a Settings class, bind the settings class in Startup and inject the Settings class in the controller constructor. This uses the IOPtions pattern * and is a cleaner and recommended approach*
    public class ConnectionSettings
    {
        public string SqlDatabase { get; set; }
    }

In your 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.
        public void ConfigureServices(IServiceCollection services)
        {
        services.Configure<ConnectionSettings>(Configuration.GetSection("ConnectionStrings"));

            services.AddControllers();
        }
    }

Then in your controller:

public class CommonController : ControllerBase
    {
        private readonly IOptions<ConnectionSettings> _connectionSettings;

        public CommonController(IOptions<ConnectionSettings> connectionSettings)
        {
            _connectionSettings = connectionSettings;
        }

        public IActionResult GetData()
        {
            SqlConnection connection = new SqlConnection(_connectionSettings.Value.SqlDatabase));
            //Get data from the database
            return null;
        }
    }
  • Related