gro*_*kky 3 c# asp.net-identity entity-framework-core asp.net-core
在 ASP.NET Core 中,EF Core 上下文是由内置 DI 容器创建的。在官方文档中,上下文是使用泛型创建的DbContextOptions<TContext>:
public class MyContext : IdentityDbContext<User> {
public MyContext(DbContextOptions<MyContext> options, ILogger<MyContext) logger) : base(options) { }
}
Run Code Online (Sandbox Code Playgroud)
然而,也有一些非泛型的例子:
public class MyContext : IdentityDbContext<User> {
public MyContext(DbContextOptions options, ILogger<MyContext) logger) : base(options) { }
}
Run Code Online (Sandbox Code Playgroud)
从源码来看它们的区别是:
类型参数: TContext:这些选项适用的上下文的类型。
我想使用非泛型类型,因为在我的设计中我有一个抽象上下文,这与 DI 容器不能很好地配合。
那么,如果我使用非泛型类型,这到底意味着什么?我的上下文无法正确配置?
小智 5
我想使用非泛型类型,因为在我的设计中我有一个抽象上下文,这与 DI 容器不能很好地配合。
这与 DI 容器配合得很好。它只查看最派生的类型,即它尝试实例化的类型。事实上,中间有一个基类是不相关的。
请注意,虽然您不能使用DbContextOptions<AbstractDbContext>,但您也不需要这样做。您可以使基类 take DbContextOptions,或使基类通用并 take DbContextOptions<ConcreteDbContext>:
abstract class AbstractDbContext : DbContext
{
protected AbstractDbContext(DbContextOptions options) : base(options)
{
}
}
class ConcreteDbContext : AbstractDbContext
{
public ConcreteDbContext(DbContextOptions<ConcreteDbContext> options) : base(options)
{
}
}
Run Code Online (Sandbox Code Playgroud)
或者
abstract class AbstractDbContext<TContext> : DbContext
where TContext : AbstractDbContext<TContext>
{
protected AbstractDbContext(DbContextOptions<TContext> options) : base(options)
{
}
}
class ConcreteDbContext : AbstractDbContext<ConcreteDbContext>
{
public ConcreteDbContext(DbContextOptions<ConcreteDbContext> options) : base(options)
{
}
}
Run Code Online (Sandbox Code Playgroud)
那么,如果我使用非泛型类型,这到底意味着什么?我的上下文无法正确配置?
采用非泛型的构造函数DbContextOptions通常也可以工作。通常情况下,你是对的,服务提供商无法解决这个问题。但是,当您调用 时,EF Core 会专门通知服务容器,serviceCollection.AddDbContext<ConcreteDbContext>(...)当DbContextOptions请求实例时,DbContextOptions<ConcreteDbContext>应提供实例。
请注意,这仅在您具有单一上下文类型时才有效。如果您有多个,服务提供商没有足够的信息来确定您需要哪一个。