vendredi 24 avril 2020

need repository design pattern advice

I have many entities and repositories. My entities are two types: Erasable and indelible. So i have two base classes for entities.

Indelible entities implements this base class:

public abstract class BaseEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public DateTime InsertedDate { get; set; }
    public DateTime? UpdatedDate { get; set; }
    //For recovering
    public DateTime? DeletedDate { get; set; }
    public bool Active { get; set; }
}

Erasable entities implement this base class:

    public abstract class BaseErasableEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]       
    public int Id { get; set; }
    public DateTime InsertedDate { get; set; }
    public DateTime? UpdatedDate { get; set; }
}

Repositories that use an erasable entity implement this base class:

 public class BaseErasableRepository<TEntity, TRepository> : DbContext, IBaseErasableRepository<TEntity> where TEntity : BaseErasableEntity where TRepository : DbContext
{
    public BaseErasableRepository(DbContextOptions<TRepository> options) : base(options)
    { }
    protected DbSet<TEntity> Entities { get; set; }
    public IEnumerable<TEntity> GetAll()
    {
        return Entities ?? throw new CannotFindEntityException();
    }
    public TEntity GetById(int id)
    {
        var entity = Entities.Find(id) ?? throw new CannotFindEntityException(id);
        return entity;
    }
    public void Update(TEntity entity)
    {
        Entities.Update(entity);
        SaveChanges();
    }
    public void Delete(TEntity entity)
    {
        Entities.Remove(entity);
        SaveChanges();
    }
    public IEnumerable<TEntity> GetFiltered(Func<TEntity, bool> condition = null)
    {
        return Entities.Where(condition) ?? throw new CannotFindEntityException();
    }
}

Repositories that use an indelible entity implement this base class:

 public class BaseRepository<TEntity, TRepository> : DbContext, IBaseRepository<TEntity> where TEntity : BaseEntity where TRepository : DbContext
{
    public BaseRepository(DbContextOptions<TRepository> options) : base(options)
    { }
    protected DbSet<TEntity> Entities { get; set; }
    public IEnumerable<TEntity> GetAll()
    {
        return Entities.Where(entity => entity.Active == true) ?? throw new CannotFindEntityException();
    }
    public TEntity GetById(int id)
    {
        var entity = Entities.Find(id) ?? throw new CannotFindEntityException(id);
        if(!entity.Active)
            throw new CannotFindEntityException();
        return entity;
    }
    public void Update(TEntity entity)
    {
        Entities.Update(entity);
        SaveChanges();
    }
    public void Delete(TEntity entity)
    { 
        var toBeDeleteEntity = GetById(entity.Id);
        toBeDeleteEntity.Active = false;
        toBeDeleteEntity.DeletedDate = DateTime.Now;
        Entities.Update(toBeDeleteEntity);
        SaveChanges();
    }
    public IEnumerable<TEntity> GetFiltered(Func<TEntity, bool> condition = null)
    {
        return Entities.Where(entity => entity.Active).Where(condition) ?? throw new CannotFindEntityException();
    }
}

My problem: I have more methods for repositories. They are the same for both repository. I have to write same code two times when i add new feature. Is there a better way to use single base repository class?

Aucun commentaire:

Enregistrer un commentaire