避免将具体的数据库上下文类注入控制器
作者:互联网
我将Entity Framework Core for MySql与数据库优先方法结合使用.
搭建好数据库后,它会生成上下文类:sakilaContext.cs(sakila是MySql中的内置数据库/方案,我用它来玩耍).
我将数据库注入了Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
var connectionString = @"server=localhost;port=1123;user=root;password=xxx;database=sakila";
services.AddDbContext<sakilaContext>(options => options.UseMySql(connectionString));
}
在我的api控制器中,我这样做如下:
private sakilaContext dbCtx;
public SakilaController(sakilaContext dbContext)
{
dbCtx = dbContext;
}
只是个小疑问,
>在这种情况下注入具体实现是错误的吗?
>如果是这样,我怎么能只注入一个接口而不是注入一个具体的实现?
谢谢
解决方法:
is it wrong to inject a concrete implementation in this case??
这取决于.如果您正在编写具有不同关注点(业务逻辑,验证,授权)的多层应用程序,或者您正在编写一个5页的应用程序以显示有限数量的用户的杂项信息?
对于小型应用程序(大多数为只读应用程序),我确实做到了这一点,因为只有很小的更改,而我不需要Over design and architect the solution.
If it is, how can I just inject an interface rather than inject a concrete implementation?
当然可以,但是在某个时候,一个类将需要一个dbcontext,它可以由需要它的对象进行DI或创建.如果确实将数据访问抽象到单独的类/接口中,则我不建议使用DI(将上下文注入到具体的数据访问中),因为具体的类型将紧密地与EF耦合.这意味着,如果您决定切换到Dapper,NHibernate或其他ORM,则无论如何都必须重写所有方法.
快速而肮脏的方式(对于小型/学习型体验,我永远不会推荐给数百万个用户系统使用)抽象DbContext的方法很简单:
public interface IUserDA
{
IQueryable<User> Users { get; }
}
public class MyDbContext : IUserDA
{
public DbSet<User> Users { get; set; }
IQueryable<User> IUserDA.Users
{
get
{
return Users; // references the DbSet
}
}
}
现在,您的MyDbContext实现了一个未与实体框架耦合的接口.
But if we inject a concrete class, does it defeat the DI purpose?
取决于您的目的.您到底想通过使用DI实现什么?您实际上是要编写真实的单元测试吗?您是否诚实地看到自己正在更改或具有多个安装/租户的接口的多个实例?
标签:asp-net-core-mvc,entity-framework-core,dependency-injection,c 来源: https://codeday.me/bug/20191108/2005931.html