Implement generic repo pattern and unitofwork

This commit is contained in:
2023-10-30 20:56:37 +01:00
parent 9b8c5412f8
commit d3d2b4b989
11 changed files with 205 additions and 180 deletions

View File

@@ -1,5 +1,5 @@
using GerbilManagerWebAPI.Models; using GerbilManagerWebAPI.Models;
using GerbilManagerWebAPI.Repositories; using GerbilManagerWebAPI.DAL;
using GerbilManagerWebAPI.Dtos; using GerbilManagerWebAPI.Dtos;
using GerbilManagerWebAPI.Converter; using GerbilManagerWebAPI.Converter;
@@ -13,20 +13,18 @@ namespace GerbilManagerWebAPI.Controllers
[Route("breeders")] [Route("breeders")]
public class BreederController : ControllerBase public class BreederController : ControllerBase
{ {
private readonly IGerbilRepository gerbilrepository; private readonly UnitOfWork unitOfWork;
private readonly IBreederRepository repository;
private readonly ILitterRepository litterRepository;
public BreederController(IBreederRepository repo) public BreederController(UnitOfWork unitOfWork)
{ {
this.repository = repo; this.unitOfWork = unitOfWork;
} }
//GET /gerbils //GET /gerbils
[HttpGet] [HttpGet]
public IEnumerable<BreederDto> GetBreeders() public IEnumerable<BreederDto> GetBreeders()
{ {
var items = repository.GetBreeders().Select( breeder => breeder.AsDto()); var items = unitOfWork.BreederRepository.Get().Select( breeder => breeder.AsDto());
return items; return items;
} }
@@ -34,7 +32,7 @@ namespace GerbilManagerWebAPI.Controllers
[HttpGet("{id}")] [HttpGet("{id}")]
public ActionResult<BreederDto> GetBreeder(Guid id) public ActionResult<BreederDto> GetBreeder(Guid id)
{ {
var item = repository.GetBreeder(id).AsDto(); var item = unitOfWork.BreederRepository.GetByID(id).AsDto();
if(item is null) if(item is null)
{ {
@@ -51,7 +49,7 @@ namespace GerbilManagerWebAPI.Controllers
Name = dto.Name, Name = dto.Name,
}; };
this.repository.CreateBreeder(breeder); this.unitOfWork.BreederRepository.Insert(breeder);
return CreatedAtAction(nameof(GetBreeder), new { id = breeder.Id}, breeder.AsDto()); return CreatedAtAction(nameof(GetBreeder), new { id = breeder.Id}, breeder.AsDto());
} }
@@ -59,7 +57,7 @@ namespace GerbilManagerWebAPI.Controllers
[HttpPut("{id}")] [HttpPut("{id}")]
public ActionResult UpdateBreeder(Guid id, UpdateBreederDto breederDto) public ActionResult UpdateBreeder(Guid id, UpdateBreederDto breederDto)
{ {
var existingItem = repository.GetBreeder(id); var existingItem = unitOfWork.BreederRepository.GetByID(id);
if(existingItem is null) if(existingItem is null)
{ {
return NotFound(); return NotFound();
@@ -69,21 +67,21 @@ namespace GerbilManagerWebAPI.Controllers
Name = breederDto.Name Name = breederDto.Name
}; };
repository.UpdateBreeder(updatedBreeder); unitOfWork.BreederRepository.Update(updatedBreeder);
return NoContent(); return NoContent();
} }
[HttpDelete("{id}")] [HttpDelete("{id}")]
public ActionResult DeleteBreeder(Guid id) public ActionResult DeleteBreeder(Guid id)
{ {
var existingLitter = repository.GetBreeder(id); var existingLitter = unitOfWork.BreederRepository.GetByID(id);
if(existingLitter is null) if(existingLitter is null)
{ {
return NotFound(); return NotFound();
} }
repository.DeleteBreeder(existingLitter); unitOfWork.BreederRepository.Delete(existingLitter);
return NoContent(); return NoContent();
} }

View File

@@ -1,5 +1,5 @@
using GerbilManagerWebAPI.Models; using GerbilManagerWebAPI.Models;
using GerbilManagerWebAPI.Repositories; using GerbilManagerWebAPI.DAL;
using GerbilManagerWebAPI.Dtos; using GerbilManagerWebAPI.Dtos;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@@ -11,20 +11,23 @@ namespace GerbilManagerWebAPI.Controllers
[Route("gerbils")] [Route("gerbils")]
public class GerbilsController : ControllerBase public class GerbilsController : ControllerBase
{ {
private readonly IGerbilRepository repository; private readonly UnitOfWork unitOfWork;
private readonly IBreederRepository breederRepository;
private readonly ILitterRepository litterRepository;
public GerbilsController(IGerbilRepository repo) public GerbilsController(UnitOfWork unitOfWork)
{ {
this.repository = repo; this.unitOfWork = unitOfWork;
} }
//GET /gerbils //GET /gerbils
[HttpGet] [HttpGet]
public IEnumerable<GerbilDto> GetGerbils() public IEnumerable<GerbilDto> GetGerbils([FromQuery]string? name)
{ {
var items = repository.GetGerbils().Select( gerbil => gerbil.AsDto()); if(name != null)
{
return unitOfWork.GerbilRepository.Get(filter: x => x.Name == name).Select( gerbil => gerbil.AsDto());
}
var items = unitOfWork.GerbilRepository.Get().Select( gerbil => gerbil.AsDto());
return items; return items;
} }
@@ -32,7 +35,7 @@ namespace GerbilManagerWebAPI.Controllers
[HttpGet("{id}")] [HttpGet("{id}")]
public ActionResult<GerbilDto> GetGerbil(Guid id) public ActionResult<GerbilDto> GetGerbil(Guid id)
{ {
var item = repository.GetGerbil(id).AsDto(); var item = unitOfWork.GerbilRepository.GetByID(id).AsDto();
if(item is null) if(item is null)
{ {
@@ -52,15 +55,15 @@ namespace GerbilManagerWebAPI.Controllers
if(dto.Litter != Guid.Empty) if(dto.Litter != Guid.Empty)
{ {
gerbil.Litter = litterRepository.GetLitter(dto.Litter); gerbil.Litter = unitOfWork.LitterRepository.GetByID(dto.Litter);
} }
if(dto.Breeder != Guid.Empty) if(dto.Breeder != Guid.Empty)
{ {
gerbil.Breeder = breederRepository.GetBreeder(dto.Breeder); gerbil.Breeder = unitOfWork.BreederRepository.GetByID(dto.Breeder);
} }
this.repository.CreateGerbil(gerbil); this.unitOfWork.GerbilRepository.Insert(gerbil);
return CreatedAtAction(nameof(GetGerbil), new { id = gerbil.Id}, gerbil.AsDto()); return CreatedAtAction(nameof(GetGerbil), new { id = gerbil.Id}, gerbil.AsDto());
} }
@@ -68,34 +71,34 @@ namespace GerbilManagerWebAPI.Controllers
[HttpPut("{id}")] [HttpPut("{id}")]
public ActionResult UpdateGerbil(Guid id, UpdateGerbilDto gerbilDto) public ActionResult UpdateGerbil(Guid id, UpdateGerbilDto gerbilDto)
{ {
var existingItem = repository.GetGerbil(id); var existingItem = unitOfWork.GerbilRepository.GetByID(id);
if(existingItem is null) if(existingItem is null)
{ {
return NotFound(); return NotFound();
} }
Gerbil updatedGerbil = existingItem with{ Gerbil updatedGerbil = existingItem with{
Breeder = breederRepository.GetBreeder(gerbilDto.Breeder.Id), Breeder = unitOfWork.BreederRepository.GetByID(gerbilDto.Breeder.Id),
Litter = litterRepository.GetLitter(gerbilDto.Litter.Id), Litter = unitOfWork.LitterRepository.GetByID(gerbilDto.Litter.Id),
Gender = (Gender) (int) gerbilDto.Gender, Gender = (Gender) (int) gerbilDto.Gender,
Name = gerbilDto.Name Name = gerbilDto.Name
}; };
repository.UpdateGerbil(updatedGerbil); unitOfWork.GerbilRepository.Update(updatedGerbil);
return NoContent(); return NoContent();
} }
[HttpDelete("{id}")] [HttpDelete("{id}")]
public ActionResult DeleteGerbil(Guid id) public ActionResult DeleteGerbil(Guid id)
{ {
var existingGerbil = repository.GetGerbil(id); var existingGerbil = unitOfWork.GerbilRepository.GetByID(id);
if(existingGerbil is null) if(existingGerbil is null)
{ {
return NotFound(); return NotFound();
} }
repository.DeleteGerbil(existingGerbil); unitOfWork.GerbilRepository.Delete(existingGerbil);
return NoContent(); return NoContent();
} }

View File

@@ -1,5 +1,5 @@
using GerbilManagerWebAPI.Models; using GerbilManagerWebAPI.Models;
using GerbilManagerWebAPI.Repositories; using GerbilManagerWebAPI.DAL;
using GerbilManagerWebAPI.Dtos; using GerbilManagerWebAPI.Dtos;
using GerbilManagerWebAPI.Converter; using GerbilManagerWebAPI.Converter;
@@ -13,20 +13,18 @@ namespace GerbilManagerWebAPI.Controllers
[Route("litters")] [Route("litters")]
public class LittersController : ControllerBase public class LittersController : ControllerBase
{ {
private readonly IGerbilRepository gerbilrepository; private readonly UnitOfWork unitOfWork;
private readonly IBreederRepository breederRepository;
private readonly ILitterRepository repository;
public LittersController(ILitterRepository repo) public LittersController(UnitOfWork unitOfWork)
{ {
this.repository = repo; this.unitOfWork = unitOfWork;
} }
//GET /gerbils //GET /gerbils
[HttpGet] [HttpGet]
public IEnumerable<LitterDto> GetLitters() public IEnumerable<LitterDto> GetLitters()
{ {
var items = repository.GetLitters().Select( litter => litter.AsDto()); var items = unitOfWork.LitterRepository.Get().Select( litter => litter.AsDto());
return items; return items;
} }
@@ -34,7 +32,7 @@ namespace GerbilManagerWebAPI.Controllers
[HttpGet("{id}")] [HttpGet("{id}")]
public ActionResult<LitterDto> GetLitter(Guid id) public ActionResult<LitterDto> GetLitter(Guid id)
{ {
var item = repository.GetLitter(id).AsDto(); var item = unitOfWork.LitterRepository.GetByID(id).AsDto();
if(item is null) if(item is null)
{ {
@@ -49,13 +47,13 @@ namespace GerbilManagerWebAPI.Controllers
Litter litter = new Litter{ Litter litter = new Litter{
Id = Guid.NewGuid(), Id = Guid.NewGuid(),
Date = dto.Date, Date = dto.Date,
Father = gerbilrepository.GetGerbil(dto.Father ?? Guid.Empty), Father = this.unitOfWork.GerbilRepository.GetByID(dto.Father ?? Guid.Empty),
Mother = gerbilrepository.GetGerbil(dto.Mother ?? Guid.Empty), Mother = this.unitOfWork.GerbilRepository.GetByID(dto.Mother ?? Guid.Empty),
Name = dto.Name, Name = dto.Name,
Strength = dto.Strength Strength = dto.Strength
}; };
this.repository.CreateLitter(litter); this.unitOfWork.LitterRepository.Insert(litter);
return CreatedAtAction(nameof(GetLitter), new { id = litter.Id}, litter.AsDto()); return CreatedAtAction(nameof(GetLitter), new { id = litter.Id}, litter.AsDto());
} }
@@ -63,7 +61,7 @@ namespace GerbilManagerWebAPI.Controllers
[HttpPut("{id}")] [HttpPut("{id}")]
public ActionResult UpdateLitter(Guid id, UpdateLitterDto litterDto) public ActionResult UpdateLitter(Guid id, UpdateLitterDto litterDto)
{ {
var existingItem = repository.GetLitter(id); var existingItem = unitOfWork.LitterRepository.GetByID(id);
if(existingItem is null) if(existingItem is null)
{ {
return NotFound(); return NotFound();
@@ -72,26 +70,26 @@ namespace GerbilManagerWebAPI.Controllers
Litter updatedLitter = existingItem with{ Litter updatedLitter = existingItem with{
Date = litterDto.Date ?? DateTime.Now, Date = litterDto.Date ?? DateTime.Now,
Strength = litterDto.Strength, Strength = litterDto.Strength,
Father = gerbilrepository.GetGerbil(litterDto.Father ?? Guid.Empty), Father = this.unitOfWork.GerbilRepository.GetByID(litterDto.Father ?? Guid.Empty),
Mother = gerbilrepository.GetGerbil(litterDto.Mother ?? Guid.Empty), Mother = this.unitOfWork.GerbilRepository.GetByID(litterDto.Mother ?? Guid.Empty),
Name = litterDto.Name Name = litterDto.Name
}; };
repository.UpdateLitter(updatedLitter); unitOfWork.LitterRepository.Update(updatedLitter);
return NoContent(); return NoContent();
} }
[HttpDelete("{id}")] [HttpDelete("{id}")]
public ActionResult DeleteLitter(Guid id) public ActionResult DeleteLitter(Guid id)
{ {
var existingLitter = repository.GetLitter(id); var existingLitter = unitOfWork.LitterRepository.GetByID(id);
if(existingLitter is null) if(existingLitter is null)
{ {
return NotFound(); return NotFound();
} }
repository.DeleteLitter(existingLitter); unitOfWork.LitterRepository.Delete(existingLitter);
return NoContent(); return NoContent();
} }

View File

@@ -0,0 +1,77 @@
using System.Linq.Expressions;
using GerbilManagerWebAPI.Models;
using Microsoft.EntityFrameworkCore;
namespace GerbilManagerWebAPI.DAL
{
public class GenericRepository<TEntity> where TEntity : class
{
internal ApplicationContext context;
internal DbSet<TEntity> dbSet;
public GenericRepository(ApplicationContext context)
{
this.context = context;
this.dbSet = context.Set<TEntity>();
}
public virtual IEnumerable<TEntity> Get(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "")
{
IQueryable<TEntity> query = dbSet;
if (filter != null)
{
query = query.Where(filter);
}
foreach (var includeProperty in includeProperties.Split
(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProperty);
}
if (orderBy != null)
{
return orderBy(query).ToList();
}
else
{
return query.ToList();
}
}
public virtual TEntity GetByID(object id)
{
return dbSet.Find(id);
}
public virtual void Insert(TEntity entity)
{
dbSet.Add(entity);
}
public virtual void Delete(object id)
{
TEntity entityToDelete = dbSet.Find(id);
Delete(entityToDelete);
}
public virtual void Delete(TEntity entityToDelete)
{
if (context.Entry(entityToDelete).State == EntityState.Detached)
{
dbSet.Attach(entityToDelete);
}
dbSet.Remove(entityToDelete);
}
public virtual void Update(TEntity entityToUpdate)
{
dbSet.Attach(entityToUpdate);
context.Entry(entityToUpdate).State = EntityState.Modified;
}
}
}

View File

@@ -0,0 +1,79 @@
using GerbilManagerWebAPI.Models;
using Microsoft.EntityFrameworkCore;
namespace GerbilManagerWebAPI.DAL
{
public class UnitOfWork : IDisposable
{
private ApplicationContext context;
private GenericRepository<Gerbil> gerbilRepository;
private GenericRepository<Litter> litterRepository;
private GenericRepository<Breeder> breederRepository;
public GenericRepository<Gerbil> GerbilRepository
{
get
{
if (this.gerbilRepository == null)
{
this.gerbilRepository = new GenericRepository<Gerbil>(context);
}
return gerbilRepository;
}
}
public GenericRepository<Litter> LitterRepository
{
get
{
if (this.litterRepository == null)
{
this.litterRepository = new GenericRepository<Litter>(context);
}
return litterRepository;
}
}
public GenericRepository<Breeder> BreederRepository
{
get
{
if (this.breederRepository == null)
{
this.breederRepository = new GenericRepository<Breeder>(context);
}
return breederRepository;
}
}
public UnitOfWork(ApplicationContext context)
{
this.context = context;
}
public void Save()
{
context.SaveChanges();
}
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
context.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
}

View File

@@ -1,4 +1,4 @@
using GerbilManagerWebAPI.Repositories; using GerbilManagerWebAPI.DAL;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
@@ -10,7 +10,7 @@ builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer(); builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(); builder.Services.AddSwaggerGen();
builder.Services.AddDbContext<ApplicationContext>(opts => opts.UseSqlServer(builder.Configuration.GetConnectionString("sqlConnection"))); builder.Services.AddDbContext<ApplicationContext>(opts => opts.UseSqlServer(builder.Configuration.GetConnectionString("sqlConnection")));
builder.Services.AddScoped<IGerbilRepository, EFGerbilRepository>(); builder.Services.AddScoped<UnitOfWork>();
var app = builder.Build(); var app = builder.Build();

View File

@@ -1,42 +0,0 @@
using GerbilManagerWebAPI.Models;
using Microsoft.EntityFrameworkCore;
namespace GerbilManagerWebAPI.Repositories
{
public class EFGerbilRepository : IGerbilRepository
{
private readonly ApplicationContext context;
public EFGerbilRepository(ApplicationContext context)
{
this.context = context;
}
public void CreateGerbil(Gerbil gerbil)
{
context.Gerbils.Add(gerbil);
context.SaveChanges();
}
public void DeleteGerbil(Gerbil gerbil)
{
context.Gerbils.Remove(gerbil);
context.SaveChanges();
}
public Gerbil GetGerbil(Guid id)
{
return context.Gerbils.Where(entity => entity.Id == id).First();
}
public IEnumerable<Gerbil> GetGerbils()
{
return context.Gerbils.ToList();
}
public void UpdateGerbil(Gerbil gerbil)
{
context.Gerbils.Update(gerbil);
context.SaveChanges();
}
}
}

View File

@@ -1,17 +0,0 @@
using GerbilManagerWebAPI.Models;
namespace GerbilManagerWebAPI.Repositories
{
public interface IBreederRepository
{
IEnumerable<Breeder> GetBreeders();
Breeder GetBreeder(Guid id);
void CreateBreeder(Breeder breeder);
void UpdateBreeder(Breeder breeder);
void DeleteBreeder(Breeder breeder);
}
}

View File

@@ -1,17 +0,0 @@
using GerbilManagerWebAPI.Models;
namespace GerbilManagerWebAPI.Repositories
{
public interface IGerbilRepository
{
IEnumerable<Gerbil> GetGerbils();
Gerbil GetGerbil(Guid id);
void CreateGerbil(Gerbil gerbil);
void UpdateGerbil(Gerbil gerbil);
void DeleteGerbil(Gerbil gerilb);
}
}

View File

@@ -1,15 +0,0 @@
using GerbilManagerWebAPI.Models;
namespace GerbilManagerWebAPI.Repositories
{
public interface ILitterRepository
{
IEnumerable<Litter> GetLitters();
Litter GetLitter(Guid id);
void CreateLitter(Litter litter);
void UpdateLitter(Litter litter);
void DeleteLitter(Litter litter);
}
}

View File

@@ -1,39 +0,0 @@
using GerbilManagerWebAPI.Models;
namespace GerbilManagerWebAPI.Repositories
{
public class InMemGerbilRepository : IGerbilRepository
{
private readonly List<Gerbil> _gerbilList = new()
{
new Gerbil() {Id = Guid.NewGuid(), Name = "Blacky", Breeder = null, Litter = null, Gender = Gender.unknown},
new Gerbil() {Id = Guid.NewGuid(), Name = "Coocky", Breeder = null, Litter = null, Gender = Gender.male},
new Gerbil() {Id = Guid.NewGuid(), Name = "Lazy", Breeder = null, Litter = null, Gender = Gender.female}
};
public IEnumerable<Gerbil> GetGerbils()
{
return _gerbilList;
}
public Gerbil GetGerbil(Guid id) => _gerbilList.SingleOrDefault(x => x.Id == id);
public void CreateGerbil(Gerbil gerbil)
{
_gerbilList.Add(gerbil);
}
public void UpdateGerbil(Gerbil gerbil)
{
var index = this._gerbilList.FindIndex(existingGerbil => existingGerbil.Id == gerbil.Id);
_gerbilList[index] = gerbil;
}
public void DeleteGerbil(Gerbil gerbil)
{
var index = this._gerbilList.FindIndex(existingGerbil => existingGerbil.Id == gerbil.Id);
_gerbilList.RemoveAt(index);
}
}
}