在Asp.Net Core中注入DbContext。具体类型还是界面?

时间:2016-04-12 20:28:05

标签: asp.net-core entity-framework-core

在Asp.Net Core项目中,我正在注入Entity Framework DbContext:

public MessageRepository(MyDbContext context) {
}

配置为:

services
  .AddEntityFramework()
  .AddSqlServer()
  .AddDbContext<Context>(x => x.UseSqlServer(connectionString);

我应该创建一个接口,IMyDbContext,然后注入它吗?

public class MyDbContext : DbContext, IMyDbContext { }

public MessageRepository(IMyDbContext context) {
}

在所有ASP.NET Core示例中,我看到正在注入具体类型MyDbContext,而不是接口......

我应该选择什么选项?

3 个答案:

答案 0 :(得分:2)

目前我自己在做一个项目,我决定使用2个这样的界面

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

public interface IApplicationDbContext : IDbContext
{
    DbSet<MyEntity> MyEntities { get; set; }
    ...
}

然后,我具体的DbContext将只实现应用程序上下文接口

public class ApplicationDbContext : DbContext, IApplicationDbContext
{
    public DbContext Instance => this

    public DbSet<MyEntity> MyEntities { get; set; }
}

这允许我将Application上下文的实现作为应用程序上下文接口注入,同时还使我可以通过Instance属性获取器访问DbContext方法,而不必将DbContext类所需的方法添加到接口中。 >

直到现在,这都很好。

答案 1 :(得分:1)

我们总是注入一个界面,因为它更容易在单元和集成测试中进行模拟。

  1. 您是否愿意更改MessageRepository构造函数的签名?它依赖于具体类型。
  2. 您是否为代码编写测试?使用和接口可以更容易地模拟数据库上下文。
  3. 如果你已经回答了&#34;没有&#34;对于上述一个或多个,注入混凝土类型;否则,请注入界面。

答案 2 :(得分:0)

在我看来,你应该总是依赖于@Uli所说的接口,但是当涉及到DbContext时,你需要记住你正在公开EntityFramework Core的DbContext的所有方法

public class MyDbContext: DbContext ,IMyDbContext {}

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

但是如果EF代码更改了DbContext并且您对项目进行了更新,那么每次更新IMyDbContext都会遇到痛苦的情况,也就是所有的单元测试。在我看来,这会给你带来很多麻烦。

这个答案/问题可以帮助您理解https://stackoverflow.com/a/6768712/819153

的原因

Unit testing EF - how to extract EF code out from BL?