我正在研究一个解耦的 web api 项目,并且它的业务逻辑在扩展中解耦(分离的项目,这给了我很多项目之间的共享代码),这就是为什么我在数据层上工作也解耦了,一切正常但唯一让我把一切都耦合到它的 AppDbContext.cs
这是一个 POC 代码,因此您可以了解我的想法(我的问题):
AppDbContext.cs
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> dbContextOptions) : base(dbContextOptions)
{
}
}
IEntity.cs
public interface IEntity<TKey>
{
TKey Id { get; set; }
}
IRepository.cs
public interface IRepository<TEntity, TKey>
where TEntity : class, IEntity<TKey>
{
IEnumerable<TEntity> GetAll();
}
GenericRepository.cs
public class GenericRepository<TEntity, TKey> : IRepository<TEntity, TKey>
where TEntity : class, IEntity<TKey>
{
private readonly AppDbContext dbContext;
public GenericRepository(AppDbContext dbContext)
{
this.dbContext = dbContext;
}
public IEnumerable<TEntity> GetAll()
{
return dbContext.Set<TEntity>().ToList();
}
}
并将其注册到组合根目录中,如下所示:
services.AddScoped(typeof(IRepository<,>), typeof(GenericRepository<,>));
如您所见,我的通用存储库使用 AppDbContext,但如果在名为 different 的不同项目中呢?或从 IdentityContext 继承,如何使我的通用存储库、DbContext 独立但在启动时可配置?
更新:
我忘了提到,在某些情况下,会有不止一个 DbContext 实现。
最佳答案
这里的最低公因数是 DbContext
。
Rafactor GenericRepository
明确依赖于 DbContext
public class GenericRepository<TEntity, TKey> : IRepository<TEntity, TKey>
where TEntity : class, IEntity<TKey> {
private readonly DbContext dbContext;
public GenericRepository(DbContext dbContext) {
this.dbContext = dbContext;
}
public IEnumerable<TEntity> GetAll() {
return dbContext.Set<TEntity>().ToList();
}
}
在组合根处,您将建立关联
services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(Configuration["database:connectionString"]));
services.AddScoped(typeof(IRepository<,>), typeof(GenericRepository<,>));
services.AddScoped<DbContext, AppDbContext>();
更新
在多个上下文的情况下,这将需要更多的抽象。在这种情况下,我为每个上下文创建了一个特定的抽象。像
IDbContext
或 ILoggingContext
public interface IDbContext : IDisposable {
int SaveContext();
DbSet<TEntity> Set<TEntity>();
//...other relevant EF members, etc
}
public interface IAppDbContext : IDbContext {
}
public interface ILogDbContext : IDbContext {
}
并让我的
DbContext
派生类从与之相关的类继承。public class AppDbContext : DbContext, IAppDbContext {
public AppDbContext(DbContextOptions<AppDbContext> dbContextOptions) : base(dbContextOptions) {
}
}
public class LogDbContext : DbContext, ILogDbContext {
public AppDbContext(DbContextOptions<LogDbContext> dbContextOptions) : base(dbContextOptions) {
}
}
从那里通用存储库将明确依赖于相关抽象
public class GenericRepository<TEntity, TKey> : IRepository<TEntity, TKey>
where TEntity : class, IEntity<TKey> {
private readonly IDbContext dbContext;
public GenericRepository(IAppDbContext dbContext) {
this.dbContext = dbContext;
}
//...code removed for brevity
}
然后在组合根进行必要的配置。
services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(Configuration["database:appConnectionString"]));
services.AddDbContext<LogDbContext>(options =>
options.UseSqlServer(Configuration["database:logConnectionString"]));
services.AddScoped(typeof(IRepository<,>), typeof(GenericRepository<,>));
services.AddScoped<IAppDbContext, AppDbContext>();
services.AddScoped<ILogDbContext, LogDbContext>();
关于c# - Net核心通用存储库模式如何在编译时不知道其类型的情况下注入(inject)DbContext?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48011706/