Asp.net core 在Asp.Net内核中注入DbContext。具体类型还是界面?

Asp.net core 在Asp.Net内核中注入DbContext。具体类型还是界面?,asp.net-core,entity-framework-core,Asp.net Core,Entity Framework Core,在Asp.Net核心项目中,我正在注入实体框架DbContext: public MessageRepository(MyDbContext context) { } 配置为: services .AddEntityFramework() .AddSqlServer() .AddDbContext<Context>(x => x.UseSqlServer(connectionString); 在所有ASP.NET核心示例中,我看到具体类型MyDbContext正

在Asp.Net核心项目中,我正在注入实体框架DbContext:

public MessageRepository(MyDbContext context) {
}
配置为:

services
  .AddEntityFramework()
  .AddSqlServer()
  .AddDbContext<Context>(x => x.UseSqlServer(connectionString);
在所有ASP.NET核心示例中,我看到具体类型MyDbContext正在被注入,而不是一个接口


我应该选择什么选项?

我们总是注入一个接口,因为在单元和集成测试中模拟更容易

  • 您是否愿意更改
    MessageRepository
    构造函数的签名?这取决于具体类型
  • 您是否为代码编写测试?使用and接口可以更容易地模拟数据库上下文
  • 如果您对上述一个或多个问题回答“否”,则注入混凝土类型;否则,注入接口

    [编辑] 使用以下命令

    context services.AddScoped<IApplicationDbContext>(provider => provider.GetService<ApplicationDbContext>());
    
    context-services.AddScoped(provider=>provider.GetService());
    
    在我看来,您应该始终依赖@Uli所说的接口,但当涉及到DbContext时,您需要记住,您正在公开EntityFramework核心的DbContext的所有方法

    公共类MyDbContext:DbContext,IMyDbContext{}

    在这种情况下,您不需要实现任何公开的方法,因为DbContext会为您处理这些方法

    但是,如果EF代码更改了DbContext,并且您对项目进行了更新,那么每次更新IMyDbContext,以及所有单元测试,您都将处于痛苦的境地。在我看来,那会让你很头疼

    这些答案/问题可以帮助您了解原因


    目前我自己正在一个项目中工作,我决定使用两个这样的接口

    public interface IDbContext : IDisposable
    {
        DbContext Instance { get; }
    }
    

    公共接口IAapplicationDBContext:IDbContext
    {
    DbSet myenties{get;set;}
    ...
    }
    
    然后,我的具体DbContext将只实现应用程序上下文接口

    public class ApplicationDbContext : DbContext, IApplicationDbContext
    {
        public DbContext Instance => this
    
        public DbSet<MyEntity> MyEntities { get; set; }
    }
    
    public类ApplicationDbContext:DbContext,iaapplicationdbcontext
    {
    公共DbContext实例=>this
    公共DbSet myenties{get;set;}
    }
    
    这允许将应用程序上下文的实现作为应用程序上下文接口注入,同时还允许我通过实例属性getter访问DbContext方法,而无需将DbContext类所需的方法添加到接口中


    到目前为止,这很有效。

    在某一点上,你必须做出一些决定,因为你不能抽象任何东西(或者你会浪费太多时间…)。我认为EF是我的基础设施组件的一部分,比如JSON.NET:如果我必须离开EF,我敢肯定这将是十年。所以不要想太多^^^好运气为什么不合并这两个接口?我真的不记得了,我想我是有原因的。这种方法公开了DBContext的所有方法,尽管它们可以通过使用存储库模式(结合一个工作类型单元)进行抽象@BernoulliIT是的,但是直接注入上下文类也会暴露所有内容。这种方法简单地消除了使用DbContext类方法和属性使注入接口保持最新所需的工作?是否使用
    AddDbContext
    AddScoped
    ?像通常使用services.AddDbContext一样添加dbcontext。然后为数据库上下文服务注册服务和实现
    public interface IApplicationDbContext : IDbContext
    {
        DbSet<MyEntity> MyEntities { get; set; }
        ...
    }
    
    public class ApplicationDbContext : DbContext, IApplicationDbContext
    {
        public DbContext Instance => this
    
        public DbSet<MyEntity> MyEntities { get; set; }
    }