Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

service.AddScoped() vs service.AddDbContext()

Tags:

asp.net-core

Let's say I want to implement different DbContexts (MySql, MsSql), but make an app completely unaware of it.

So with "AddScoped" (or any other) method I can register things like:

<AppDbContextContract, AppDbContextMySql>
<AppDbContextContract, AppDbContextMsSql>

Or even hide each of it behind factories.

But with AddDbContext() I can't even see an obvious way to put the implementation I need instead of abstract AppDbContextContract.

What is the use of AddDbContext() method aside of providing an easy way to add a DB context in a basic application? Should I prefer "general" DI methods over it?

like image 499
yaapelsinko Avatar asked Mar 10 '17 11:03

yaapelsinko


1 Answers

.AddDbContext also allows you to configure it at the same time. Configuration can't work with the abstract type, since you have to pass a IDbContextOptionsBuilder<T> into your DbContext, where T is your concrete implementation.

However, you can use both together if you want to inject the abstract class.

services.AddDbContext<AppDbContextMySql>( /* configure it */);
services.AddDbContext<AppDbContextSqlServer>( /* configure it */);

services.AddScoped<AppDbContextContract>(p => p.GetRequiredService<AppDbContextMySql>());
services.AddScoped<AppDbContextContract>(p => p.GetRequiredService<AppDbContextSqlServer>());

Not using .AddDbContext you'd need to write

var dbOptionsA = new DbContextOptionsBuilder<AppDbContextMySql>();
dbOptionsA.UseMySql(...);
services.AddSingleton(dbOptionsA);
var dbOptionsB = new DbContextOptionsBuilder<AppDbContextSqlServer>();
dbOptionsB.UseSqlServer(...);
services.AddSingleton(dbOptionsB);

services.AddScoped<AppDbContextContract,AppDbContextMySql>();
services.AddScoped<AppDbContextContract,AppDbContextSqlServer>();

Not so pretty, eh?

But if the configuration happens from outside, then yes. You could only have a single AppDbContextContract, which accepts a IDbContextOptions<AppDbContextContract> and configure this in a library. You'd still have to register IDbContextOptions<AppDbContextContract> during startup somewhere.

like image 99
Tseng Avatar answered Nov 05 '22 10:11

Tseng