Reputation: 1120
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
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