[英]How can I use unit of work pattern with generic repository pattern in my ASP.NET Core Web API project?
There are many examples on the inte.net about the use of unit of work and generic repository together, but I couldn't find exactly how to apply the unit of work repository pattern to my own project. inte.net 上有很多关于一起使用工作单元和通用存储库的示例,但我找不到确切的如何将工作单元存储库模式应用到我自己的项目中。 Because everyone did it differently.因为每个人做的都不一样。
Actually, I set up the unit of work structure, but I don't quite understand how I can use it in my own project?实际上,我设置了工作单元结构,但我不太明白如何在我自己的项目中使用它? How can I apply the unit of work repository I made to my own project?如何将我创建的工作单元存储库应用到我自己的项目中? Can you help me with this?你能帮我吗? Can you tell me if I have a mistake?如果我有错误,你能告诉我吗? This is how I saw the unit of work repository on the inte.net and implemented it.这就是我在 inte.net 上看到工作单元存储库并实现它的方式。
First of all, if I just talk about my project, my project is an ASP.NET Core Web API project and basically a 3-layer structure:首先,如果我只说我的项目,我的项目是一个 ASP.NET Core Web API 项目,基本上是一个 3 层结构:
I'm doing these with the generic repository.我正在使用通用存储库执行这些操作。 As an example, I am sharing some of my code below.例如,我在下面分享我的一些代码。
I just shared category as an example, but I have more than one class like category.我只是以共享类别为例,但我有多个 class 喜欢的类别。
API layer - CategoriesController
: API 层 - CategoriesController
控制器:
[Route("api/[controller]")]
[ApiController]
public class categoriesController : ControllerBase
{
private ICategoryService category_service;
DatabaseContext c = new DatabaseContext();
public categoriesController(ICategoryService category_service)
{
this.category_service = category_service;
}
[HttpGet("getall")]
public async Task<IActionResult> Get()
{
return Ok(await category_service.TGetAll());
}
[HttpGet("getbyid/{id}")]
public async Task<IActionResult> GetByIdCategory(int id)
{
var category = await category_service.TGetById(id);
if (category != null)
{
return Ok(category); // 200 ok
}
else
{
return NotFound(); //404 not found
}
}
[HttpPost("add")]
public async Task<IActionResult> Add(Category category)
{
var result = category_service.TAdd(category);
if (result != null)
{
return Ok(result);
}
return BadRequest(result);
}
}
Business layer - CategoryManager
:业务层CategoryManager
:
public class CategoryManager:ICategoryService
{
ICategoryDal _categoryDal;
public CategoryManager(ICategoryDal _cateogoryDal)
{
this._categoryDal = _cateogoryDal;
}
public async Task<List<Category>> TGetAll()
{
return await _categoryDal.GetListAll();
}
public async Task<Category> TGetById(int id)
{
return await _categoryDal.GetByID(id);
}
public async Task TAdd(Category entity)
{
await _categoryDal.Insert(entity);
}
public async Task TDelete(Category entity)
{
await _categoryDal.Delete(entity);
}
public async Task TUpdate(Category entity)
{
await _categoryDal.Update(entity);
}
}
Data Access layer - CategoryRepository
:数据访问层 - CategoryRepository
:
public class CategoryRepository : GenericRepository<Category>, ICategoryDal
{
}
GenericRepository
: GenericRepository
:
public class GenericRepository<T> : IGenericDal<T> where T : class
{
protected DatabaseContext dbContext;
public GenericRepository(DatabaseContext context)
{
dbContext = context;
}
public async Task Delete(T t)
{
dbContext.Remove(t);
await dbContext.SaveChangesAsync();
}
public IQueryable<T> FindByCondition(Expression<Func<T, bool>> expression)
{
return dbContext.Set<T>()
.Where(expression)
.AsNoTracking();
}
public async Task<T> GetByID(int id)
{
return await dbContext.Set<T>().FindAsync(id);
}
public async Task<List<T>> GetListAll()
{
return await dbContext.Set<T>().ToListAsync();
}
public async Task<List<T>> GetListAll(Expression<Func<T, bool>> filter)
{
return await dbContext.Set<T>()
.Where(filter)
.ToListAsync();
}
public async Task Insert(T t)
{
await dbContext.AddAsync(t);
await dbContext.SaveChangesAsync();
}
public async Task Update(T t)
{
var updatedEntity = dbContext.Entry(t);
updatedEntity.State = EntityState.Modified;
dbContext.SaveChanges();
}
}
UnitOfWork
: UnitOfWork
:
public class UnitOfWorkRepository : IUnitOfWork
{
private readonly DatabaseContext _dbContext;
private IDbContextTransaction _transaction;
private bool _disposed;
public UnitOfWorkRepository(DatabaseContext dbContext)
{
_dbContext = dbContext;
}
public bool BeginNewTransaction()
{
try
{
_transaction = _dbContext.Database.BeginTransaction();
return true;
}
catch (Exception ex)
{
return false;
}
}
protected virtual void Dispose(bool disposing)
{
if (!this._disposed)
{
if (disposing)
{
_dbContext.Dispose();
}
}
this._disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public IGenericDal<T> GetRepository<T>() where T : class
{
return new GenericRepository<T>(_dbContext);
}
public bool RollBackTransaction()
{
try
{
_transaction.Rollback();
_transaction = null;
return true;
}
catch (Exception ex)
{
return false;
}
}
public int SaveChanges()
{
var transaction = _transaction != null ? _transaction : _dbContext.Database.BeginTransaction();
using (transaction)
{
try
{
// Context boş ise hata fırlatıyoruz
if (_dbContext == null)
{
throw new ArgumentException("Context is null");
}
// SaveChanges metodundan dönen int result ı yakalayarak geri dönüyoruz.
int result = _dbContext.SaveChanges();
// Sorun yok ise kuyruktaki tüm işlemleri commit ederek bitiriyoruz.
transaction.Commit();
return result;
}
catch (Exception ex)
{
// Hata ile karşılaşılır ise işlemler geri alınıyor
transaction.Rollback();
throw new Exception("Error on SaveChanges ", ex);
}
}
}
}
IUnitOfWork
: IUnitOfWork
:
public interface IUnitOfWork : IDisposable
{
bool BeginNewTransaction();
bool RollBackTransaction();
IGenericDal<T> GetRepository<T>() where T : class;
int SaveChanges();
}
You can check the source in the link.您可以检查链接中的来源。 https://www.linkedin.com/pulse/repository-unit-work-patterns.net-core-dimitar-iliev/ https://www.linkedin.com/pulse/repository-unit-work-patterns.net-core-dimitar-iliev/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.