Commit a23dc773 authored by Almouhannad's avatar Almouhannad

(B) Add unit of work

parent 6529f82d
......@@ -2,14 +2,16 @@
namespace Domain.Repositories.Base
{
// CRUD operations
// Note that queries are async, but commands are NOT
// Since the persist operation is done by UnitOfWork
public interface IRepository<TEntity>
where TEntity : Entity
{
// CRUD operations
#region Create operation
public Task<TEntity> CreateAsync(TEntity entity);
public void Create(TEntity entity);
#endregion
......@@ -23,13 +25,13 @@ namespace Domain.Repositories.Base
#region Update oprtation
public Task<TEntity> UpdateAsync(TEntity entity);
public void Update(TEntity entity);
#endregion
#region Delete operation
public Task DeleteAsync(int id);
public void Delete(TEntity entity);
#endregion
}
......
namespace Domain.UnitOfWork;
public interface IUnitOfWork
{
public Task SaveChangesAsync();
}
using Domain.Primitives;
using Domain.Repositories.Base;
using Domain.UnitOfWork;
using Microsoft.EntityFrameworkCore;
using Persistence.Context;
using Persistence.Repositories.Specifications.Base;
using Persistence.Repositories.Specifications.Evaluator;
namespace Persistence.Repositories.Base;
......@@ -10,9 +13,9 @@ public class Repositroy<TEntity> : IRepository<TEntity> where TEntity : Entity
#region Ctor DI for context
private readonly ClinicsDbContext _context;
protected readonly ClinicsDbContext _context;
public Repositroy(ClinicsDbContext context)
public Repositroy(ClinicsDbContext context, IUnitOfWork unitOfWork)
{
_context = context;
}
......@@ -20,30 +23,31 @@ public class Repositroy<TEntity> : IRepository<TEntity> where TEntity : Entity
#endregion
#region Apply specification
protected IQueryable<TEntity> ApplySpecification (Specification<TEntity> specification)
{
return SpecificationEvaluator.GetQuery(_context.Set<TEntity>(), specification);
}
#endregion
#region CRUD
// CRUD operations
#region Create operation
public async Task<TEntity> CreateAsync(TEntity entity)
public virtual void Create(TEntity entity)
{
var query = await _context.Set<TEntity>().AddAsync(entity);
await _context.SaveChangesAsync();
return query.Entity;
_context.Set<TEntity>().Add(entity);
}
#endregion
#region Read operations
public async Task<TEntity?> GetByIdAsync(int id)
public virtual async Task<TEntity?> GetByIdAsync(int id)
{
return await _context.Set<TEntity>().FindAsync(id);
}
public async Task<ICollection<TEntity>> GetAllAsync()
public virtual async Task<ICollection<TEntity>> GetAllAsync()
{
return await _context.Set<TEntity>().ToListAsync();
}
......@@ -52,28 +56,20 @@ public class Repositroy<TEntity> : IRepository<TEntity> where TEntity : Entity
#region Update operation
public async Task<TEntity> UpdateAsync(TEntity entity)
public virtual void Update(TEntity entity)
{
var query = _context.Set<TEntity>().Update(entity);
await _context.SaveChangesAsync();
return query.Entity;
_context.Set<TEntity>().Update(entity);
}
#endregion
#region Delete operation
public async Task DeleteAsync(int id)
public virtual void Delete(TEntity entity)
{
var entity = await GetByIdAsync(id);
if (entity is not null)
_context.Set<TEntity>().Remove(entity);
await _context.SaveChangesAsync();
_context.Set<TEntity>().Remove(entity);
}
#endregion
#endregion
}
using Domain.Primitives;
using System.Linq.Expressions;
namespace Persistence.Specifications.Base;
namespace Persistence.Repositories.Specifications.Base;
public abstract class Specification<TEntity> where TEntity : Entity
{
......
using Domain.Primitives;
using Microsoft.EntityFrameworkCore;
using Persistence.Specifications.Base;
using Persistence.Repositories.Specifications.Base;
namespace Persistence.Specifications.Evaluator;
namespace Persistence.Repositories.Specifications.Evaluator;
public static class SpecificationEvaluator
{
......
using Domain.UnitOfWork;
using Persistence.Context;
namespace Persistence.UnitOfWork;
public class UnitOfWork : IUnitOfWork
{
private readonly ClinicsDbContext _context;
public UnitOfWork(ClinicsDbContext context)
{
_context = context;
}
public async Task SaveChangesAsync()
{
try
{
await _context.SaveChangesAsync();
}
catch (Exception)
{
// TODO: Log errors using ILogger
//throw;
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment