将 Genegic 接口添加到服务中。这段代码是如何工作的?
Add Genegic interface into service. How does this code work?
我正在尝试在我的 Dotnet 核心项目中实施存储库和工作单元。
我有这样一行代码:
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 class 中处理,服务从构造函数中注入:
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));
}
我认为你是对的。一些修复是:
- 在 EfRepository 中 class。
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.com/steliosgiakoumidis/NotificationDatabase
关于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 方法通常不在应用层的 database/infrastructure 层调用,而是调用。
使用工作单元可以节省相当多的注射。由于您将所有存储库捆绑到一个 UoW 中,因此您将其注入。
我自己我没有使用过通用 repostiries 和 UoW,但我更喜欢使用抽象 class,但主要思想是相同的。
我正在尝试在我的 Dotnet 核心项目中实施存储库和工作单元。
我有这样一行代码:
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 class 中处理,服务从构造函数中注入:
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));
}
我认为你是对的。一些修复是:
- 在 EfRepository 中 class。
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.com/steliosgiakoumidis/NotificationDatabase
关于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 方法通常不在应用层的 database/infrastructure 层调用,而是调用。 使用工作单元可以节省相当多的注射。由于您将所有存储库捆绑到一个 UoW 中,因此您将其注入。
我自己我没有使用过通用 repostiries 和 UoW,但我更喜欢使用抽象 class,但主要思想是相同的。