service.AddScoped()与service.AddDbContext()

yaa*_*nko 2 asp.net-core

假设我要实现不同的DbContext(MySql,MsSql),但使应用程序完全不知道它。

因此,使用“ AddScoped”(或任何其他)方法,我可以注册:

<AppDbContextContract, AppDbContextMySql>
<AppDbContextContract, AppDbContextMsSql>
Run Code Online (Sandbox Code Playgroud)

甚至将它们隐藏在工厂后面。

但是,有了AddDbContext(),我什至看不到一种明显的方式来放置所需的实现,而不是抽象的AppDbContextContract。

除了提供在基本应用程序中添加数据库上下文的简便方法之外,AddDbContext()方法还有什么用?我是否应该首选“通用” DI方法?

Tse*_*eng 5

.AddDbContext还允许您同时配置它。配置不能与抽象类型一起使用,因为您必须将a传递IDbContextOptionsBuilder<T>到DbContext中,T具体实现在哪里。

但是,如果要注入抽象类,可以将两者一起使用。

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

services.AddScoped<AppDbContextContract>(p => p.GetRequiredService<AppDbContextMySql>());
services.AddScoped<AppDbContextContract>(p => p.GetRequiredService<AppDbContextSqlServer>());
Run Code Online (Sandbox Code Playgroud)

不使用.AddDbContext你需要写

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>();
Run Code Online (Sandbox Code Playgroud)

不太漂亮吧?

但是,如果配置是从外部进行的,则可以。您只能有一个AppDbContextContract接受IDbContextOptions<AppDbContextContract>并在库中进行配置的。您仍然需要IDbContextOptions<AppDbContextContract>在启动期间在某个地方进行注册。