【发布时间】:2019-03-26 06:06:06
【问题描述】:
尝试创建一个通用存储库类,用于使用依赖注入、工作单元和存储库模式在 C# 中实现基本的 CRUD 操作。
我对这些概念很陌生。以下是我的代码。
public interface IUnitOfWork
{
IApplicationUserRepository Users { get; }
ICompanyRepository Companies { get; }
void Complete();
}
public class UnitOfWork : IUnitOfWork
{
private readonly ApplicationDbContext _context;
public IApplicationUserRepository Users { get; private set; }
public ICompanyRepository Companies { get; private set; }
public UnitOfWork(ApplicationDbContext context)
{
_context = context;
Users = new ApplicationUserRepository(context);
Companies = new CompanyRepository(context);
}
public void Complete()
{
_context.SaveChanges();
}
}
public interface IApplicationDbContext
{
DbSet<Company> Companies { get; set; }
IDbSet<ApplicationUser> Users { get; set; }
IDbSet<IdentityRole> Roles { get; set; }
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>, IApplicationDbContext
{
public DbSet<Company> Companies { get; set; }
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
public abstract class GenericRepository<T> : IGenericRepository<T>
where T : class, new()
{
protected GenericRepository(ApplicationDbContext context)
{
_dbContext = context;
}
private ApplicationDbContext _dbContext;
private static IEnumerable<T> entity;
public IEnumerable<T> Get(bool forceRefresh = false)
{
if (forceRefresh || entity == null)
entity = _dbContext.Set<T>();
return entity;
}
public async Task AddAsync(T entity)
{
_dbContext.Set<T>().Add(entity);
await _dbContext.SaveChangesAsync();
}
public async Task RemoveAsync(T entity)
{
_dbContext.Set<T>().Remove(entity);
await _dbContext.SaveChangesAsync();
}
}
在上面的代码中,我想传递 IApplicationDBContext 而不是 ApplicationDBContext 以消除紧密耦合,但是当我使用 IApplicationDbContext 时,对 Set 和 SaveChanges 等方法的访问将丢失。如何在不丢失这些方法的情况下删除上述依赖项。我想通过构造函数从我的子类存储库中传递实际上下文。
【问题讨论】:
-
工作单元模式不会替换存储库(或者在您的情况下是通用存储库,它在控制器和存储库之间添加了另一层抽象,您可以查看详细示例here
-
用我所有的类和接口更新了代码,我在 UnitOfWork 中有一个上下文,并且想在整个项目中使用相同的上下文,不想在我的泛型类中创建一个新的上下文。
-
在我看来,你不会通过注入
IApplicationDbContext... 再次实现任何目标,这是我的观点,但我认为应该使用一个只有 1 个实现的接口,这是有充分理由的...在这种情况下,我看不到通过注入接口为您的代码添加任何价值...如果是我,我只会注入ApplicationDbContext...这样您的代码更小更容易了解。 -
如果要制作接口,请参阅this question...
标签: c# generics dependency-injection repository-pattern unit-of-work