我想在我的Dotnet核心项目中实现Repository和Unit Of Work。
我有一行代码是这样的,我想在我的Dotnet核心项目中实现Repository和Unit Of Work。
services.AddScoped(typeof(IEfRepository<>), typeof(EfRepository<>));
public interface IEfRepository<TEntity> where TEntity : class
{
/// <summary>
/// SingleOrDefault expression
/// </summary>
/// <param name="predicate"></param>
/// <returns></returns>
Task<TEntity> SingleOrDefaultAsync(Expression<Func<TEntity, bool>> predicate);
...
并实现:
public class EfRepository<TEntity> : IEfRepository<TEntity> where TEntity : class
{
/// <summary>
/// Fields
/// </summary>
private readonly DbContext _dbContext;
private DbSet<TEntity> _entities;
/// <summary>
/// Initialize a new instance of the <see cref=" EfRepository{TEntity}"/> class
/// </summary>
/// <param name="dbContext"></param>
public EfRepository(DbContext dbContext)
{
_dbContext = dbContext;
}
当请求从调解器发出时 它在Handler类中处理,服务从contructor注入。
public class KiemtracongtrinhQueryHandler : IRequestHandler<GetKiemtracongtrinhQuery, GKiemtracongtrinhDto>,
IRequestHandler<ListKiemtracongtrinhQuery, IEnumerable<GKiemtracongtrinhDto>>
{
private readonly IGKiemtracongtrinhRepository _gKiemtracongtrinhRepository;
private readonly IMapper _mapper;
/// <summary>
/// Initialize a new instance of the <see cref="KiemtracongtrinhQueryHandler"/> class
/// </summary>
/// <param name="gKiemtracongtrinhRepository"></param>
/// <param name="mapper"></param>
public KiemtracongtrinhQueryHandler(IGKiemtracongtrinhRepository gKiemtracongtrinhRepository,
IMapper mapper)
{
_gKiemtracongtrinhRepository = gKiemtracongtrinhRepository ?? throw new ArgumentNullException(nameof(gKiemtracongtrinhRepository));
_mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
}
我认为你的方法是对的。一些修复方法是
public class EfRepository<TEntity> : IEfRepository<TEntity> where TEntity : class
{
/// <summary>
/// Fields
/// </summary>
private readonly DbContext _dbContext;
/// <summary>
/// Initialize a new instance of the <see cref=" EfRepository{TEntity}"/> class
/// </summary>
/// <param name="dbContext"></param>
public EfRepository(DbContext dbContext)
{
_dbContext = dbContext;
}
/// <summary>
/// Initialize a new instance of the <see cref=" EfRepository{TEntity}"/> class
/// </summary>
/// <param name="dbContext"></param>
public EfRepository(DbContext dbContext)
{
_dbContext = dbContext;
}
///Example method
public async Task AddItem(T item)
{
_context.Set<T>().Add(item);
return await _context.SaveChangesAsync();
}
///Example method
public async Task<List<T>> GetAllRecords(T exampleItem)
{
return _context.Set<T>().ToList();
}
我不明白为什么DbEtities要放在这里。
2) 你的处理程序。
public class KiemtracongtrinhQueryHandler : IRequestHandler<GetKiemtracongtrinhQuery, GKiemtracongtrinhDto>,
IRequestHandler<ListKiemtracongtrinhQuery, IEnumerable<GKiemtracongtrinhDto>>
{
private readonly IEfRepository<GKiemtracongtrinhRepository> _gKiemtracongtrinhRepository;
private readonly IMapper _mapper;
/// <summary>
/// Initialize a new instance of the <see cref="KiemtracongtrinhQueryHandler"/> class
/// </summary>
/// <param name="gKiemtracongtrinhRepository"></param>
/// <param name="mapper"></param>
public KiemtracongtrinhQueryHandler(IEfRepository<GKiemtracongtrinhRepository> gKiemtracongtrinhRepository,
IMapper mapper)
{
_gKiemtracongtrinhRepository = gKiemtracongtrinhRepository ?? throw new ArgumentNullException(nameof(gKiemtracongtrinhRepository));
_mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
}
在处理程序中,你需要传递通用仓库。
如果你愿意,你可以看看这个例子。https:/github.comsteliosgiakoumidisNotificationDatabase
关于UnitOfWork,你可以使用它的方法如下。
public interface IUnitOfWork
{
IRepository2 Repository1{ get; }
IRepository2 Repository2 { get; }
IRepository3 Repository3 { get; }
Task<bool> SaveChangesAsync();
}
public class UnitOfWork : IUnitOfWork
{
public IRepository1 Repository1 { get; }
public IRepository2 Repository2 { get; }
public IRepository3 Repository3 { get; }
private readonly _dbContext;
public UnitOfWork(IRepository1 repository1, IRepository2 repository2,
IRepository3 repository3)
{
Repository1 = repository1;
Repository2 = repository2;
Repository3 = repository3;
}
public async Task<bool> SaveChangesAsync()
{
try
{
await _context.SaveChangesAsync();
}
catch (Exception ex)
{
Log.Error($"An error occured when saving changes to the database.)
}
}
}
好的做法是在UnitOfWork中传递SaveChanges,并在所有数据库操作完成后执行该方法。SaveChanges方法通常不在应用层的databaseinfrastructure层中调用,而是在应用层中调用。使用工作单元,你可以节省相当多的注入。因为你把所有的仓库都捆绑在一个UoW中,你可以用这个来代替注入。
我自己没有使用过通用的存储库和UoW,但我更喜欢使用一个抽象类来代替,但主要的想法是一样的。