Paul Duer
Paul Duer

Reputation: 1120

Understanding Dependency Injection for database connections in Dot Net Core

I'm using the excellent database library NReco.Data for a new MVC project I am working on with MVC Core.

I'm trying to use dependency injection as much as possible. But, what is confusing me is this. Based on the code below from my Startup.cs, how could I instantiate another DbDataAdapter that would point at a different database (or connection string)?

public void ConfigureServices(IServiceCollection services)
{
    var dbconnectStringAppSettings = Configuration["DBConnectString"];
    services.AddDbContext<MisoIRListservDbContext>(options => options.UseSqlServer(dbconnectStringAppSettings));

    InjectNRecoDataService(services);

    // Repositories
    services.AddScoped<ListSettingRepository>();
    services.AddScoped<ListCategoryRepository>();
    services.AddScoped<MailingListRepository>();
    services.AddScoped<LISTSERVRepository>();

    // Services
    services.AddScoped<ListServEmailMailingListService>();
    services.AddScoped<ListCategoryMailingListService>();

    services.AddMvc();        

}

private void InjectNRecoDataService(IServiceCollection services)
{
    services.AddSingleton<IDbFactory, DbFactory>(servicePrv => new DbFactory(SqlClientFactory.Instance)
    {
        LastInsertIdSelectText = "SELECT @@IDENTITY"
    });
    services.AddSingleton<IDbCommandBuilder, DbCommandBuilder>(servicePrv =>
    {
        var dbCmdBuilder = new DbCommandBuilder(servicePrv.GetRequiredService<IDbFactory>());
        return dbCmdBuilder;
    });
    services.AddScoped<IDbConnection>(servicePrv =>
    {
        var dbCoreContext = servicePrv.GetRequiredService<MisoIRListservDbContext>();
        var conn = dbCoreContext.Database.GetDbConnection();
        return conn;
    });
    services.AddScoped<DbDataAdapter>();
}

Upvotes: 1

Views: 2234

Answers (1)

Gigi
Gigi

Reputation: 29421

My viewpoint is that database-specific stuff like SQL connections shouldn't go in the IoC container; that results in the very problem of reuse you're facing, alongside other issues of managing their life cycle.

It is a lot better to keep all database-related stuff within a class called a repository (repository pattern) which encapsulates all of that and makes the outside world oblivious to the details - once you give it an interface, you can easily put that in an IoC container and swap it out (e.g. for unit testing). You'll want to have different repositories for different areas of your domain.

Eventually you'll also want to look into the unit of work pattern for more advanced scenarios involving transactions across different repositories.

Upvotes: 1

Related Questions