?

Log in

No account? Create an account

How to inject a database connection in an ASP.NET Core application. - Silnith’s Lair

Jul. 29th, 2018

07:51 pm - How to inject a database connection in an ASP.NET Core application.

Previous Entry Share

This is a follow-up to my last post, the one about database connections in C# and .NET Core. I figured out a way to make using a database connection in C# a tad less of an anti-pattern and a tad more like how Java does it. In particular, I found a slick and simple way to encapsulate the connection string so that components using the database connection do not need to know or care what the connection string is.

namespace Foo
{
    class Startup
    {
        public IConfiguration Configuration { get; }

        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton<DbConnectionStringBuilder>(new SqlConnectionStringBuilder
                {
                    ConnectionString = Configuration.GetConnectionString("ImportantDatabase");
                    Password = Configuration.GetSection("SecurePasswords").GetValue<string>("ImportantDatabasePassword");
                });
             services.AddTransient<IDbConnection>(provider =>
                {
                    var builder = provider.GetRequiredService<DbConnectionStringBuilder>();
                    var providerFactory = DbProviderFactories.GetFactory("System.Data.SqlClient");
                    var conn = providerFactory.CreateConnection();
                    conn.ConnectionString = builder.ConnectionString;
                    return conn;
                });
        }
    }
}

Then in your consuming code, all you need to do is retrieve an IDbConnection from the injection system.

namespace Foo.Bar
{
    class DAL
    {
        private readonly IServiceProvider _provider;

        public DAL(IServiceProvider provider)
        {
            _provider = provider;
        }

        public void SomethingImportant()
        {
            using (var dbConnection = _provider.GetRequiredService<IDbConnection>())
            {
                dbConnection.Open();

                using (var dbCommand = dbConnection.CreateCommand())
                {
                    // do stuff
                }
            }
        }
    }
}

I apologize if I got any class names or method names wrong. I am writing this from memory, because the code I wrote is at work and I am at home.

I split out the database password because I firmly believe that database connection strings should be standard configuration, and that they should not contain credentials. Store the secret credentials separately. And obviously the provider invariant name ("System.Data.SqlClient") should be configuration instead of hard-coded. This is just example code to demonstrate the technique.