【发布时间】:2021-12-28 08:33:57
【问题描述】:
我有项目 A,它是一个类库,项目 B 使用 A。项目 A 是一个通用帮助库,可以跨项目(例如 B)使用。
EF Core 数据上下文和数据实体需要在项目 B 中定义(因为它们可能因项目而异),但我需要将数据上下文注入到项目 A 中服务类的构造函数中(以通用方式处理所有内容) )。 在项目 B 中,我有数据上下文
public class MyDataContext : DbContext
{
public MyDataContext(DbContextOptions<MyDataContext> options): base(options)
{
}
public DbSet<Test> Tests { get; set; }
}
在项目 A 中,我有实现 IUnitOfWork 的 UnitOfWork 类。在它的构造函数中,我需要注入数据上下文。但是,由于项目 A 不能引用项目 B(项目 A 是通用的),我不能在参数列表中使用数据上下文的实际名称。由于datacontext继承自DbContext,所以我尝试了
public UnitOfWork(DbContext dc){...}
在项目B的启动中,我有
services.AddDbContext<MyDataContext>(options =>
{
options.UseSqlServer("...<the connection string> ...");
});
services.AddScoped<IUnitOfWork, UnitOfWork>();
一切都可以编译,但在运行时需要创建 UnitOfWork 时,我收到错误
System.AggregateException: Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: IUnitOfWork Lifetime: Scoped ImplementationType: UnitOfWork': Unable to resolve service for type 'Microsoft.EntityFrameworkCore.DbContext' while attempting to activate 'UnitOfWork'.)
内部异常是
InvalidOperationException: Unable to resolve service for type 'Microsoft.EntityFrameworkCore.DbContext' while attempting to activate 'UnitOfWork'.
非常感谢任何帮助。
编辑 我被要求在 cmets 中提供 UnitOfWork 类的详细信息。所以这里是
public class UnitOfWork : IUnitOfWork
{
private readonly DbContext dc;
private readonly IServiceProvider serviceProvider;
public UnitOfWork(DbContext dc, IServiceProvider serviceProvider)
{
this.dc = dc;
this.serviceProvider = serviceProvider;
}
public void BeginTransaction()
{
dc.Database.BeginTransaction();
}
public void BeginTransaction(IsolationLevel isolationLevel)
{
dc.Database.BeginTransaction(isolationLevel);
}
public void CommitTransaction()
{
dc.Database.CommitTransaction();
}
public void RollbackTransaction()
{
dc.Database.RollbackTransaction();
}
public bool IsTransactionActive()
{
return dc.Database.CurrentTransaction != null;
}
public async Task<bool> SaveAsync()
{
return await dc.SaveChangesAsync() > 0;
}
public bool Save()
{
return dc.SaveChanges() > 0;
}
}
【问题讨论】:
-
可以添加工作单元类吗?
-
原始问题已编辑以包含详细信息
-
你破坏了 EF Core。您的问题不是 DI,而是使用 EF Core 的完全错误的方式。 DbContext 已经是一个多实体的工作单元。 DbSet 已经是一个存储库。绝对没有理由使用显式事务。 DbContext 缓存所有更改。如果您不致电
SaveChanges,则所有更改都将被丢弃。如果这样做,所有更改都将使用内部事务进行持久化。在您加载数据或调用SaveChanges之前,无需连接到数据库 -
这里真正的解决方案是删除此代码并简单地使用
MyDataContext它应该工作的方式。将其注入到您的类中,并且只调用一次SaveChanges以保留所有缓存的更改。如果您不这样做,则在处理MyDataContext后,所有更改都将被丢弃。你的“工作单元”类不能做的事情,因为它没有实现IDisposable。 -
IMO 在某些情况下,在应用程序中抽象 EF Core 是个好主意。如果他决定使用 NoSQL 而不是关系数据库,那么过渡会更容易。它还可以简化单元测试。
标签: c# .net-core dependency-injection entity-framework-core