Home > Blockchain >  How can I write the following code in layered architecture and generic?
How can I write the following code in layered architecture and generic?

Time:04-07

I am developing a project in layered architecture to improve myself.Now let me show you my layers.

 public class EfEntityRepositoryBase<TEntity, TContext> : IEntityRepository<TEntity>
        where TEntity : class, IEntity, new()
        where TContext : DbContext, new()
    {
        public void Add(TEntity entity)
        {
            using (var context = new TContext())
            {
                var addedEntity = context.Entry(entity);
                addedEntity.State = EntityState.Added;
                context.SaveChanges();
            }
        }

        public async void AddAsync(TEntity entity)
        {
            using (var context = new TContext())
            {
                context.Add(entity);
                await context.SaveChangesAsync();
            }
        }

        public void Delete(TEntity entity)
        {
            using (var context = new TContext())
            {
                var removedEntity = context.Entry(entity);
                removedEntity.State = EntityState.Deleted;
                context.SaveChanges();
            }
        }

        public TEntity Get(Expression<Func<TEntity, bool>> filter = null)
        {
            using (var context = new TContext())
            {
                return context.Set<TEntity>().SingleOrDefault(filter);
            }
        }

        public List<TEntity> GetList(Expression<Func<TEntity, bool>> filter = null)
        {
            using (var context = new TContext())
            {
                return filter == null
                    ? context.Set<TEntity>().ToList()
                    : context.Set<TEntity>().Where(filter).ToList();
            }
        }
        public void Update(TEntity entity)
        {
            using (var context = new TContext())
            {
                var updatedEntity = context.Entry(entity);
                updatedEntity.State = EntityState.Modified;
                context.SaveChanges();
            }
        }
    }

This is my data access layer.

public class IProductManager : IProductService
    {
        private IProductDal _productDal;

        public IProductManager(IProductDal productDal)
        {
            _productDal = productDal;
        }

        public void Add(Product product)
        {
            _productDal.Add(product);
        }

        public void AddAsync(Product product)
        {
            _productDal.AddAsync(product);
        }

        public void Delete(int productId)
        {
            _productDal.Delete(new Product { ProductId = productId });
        }

        public List<Product> GetAll()
        {
            return _productDal.GetList();
        }
        public List<Product> GetByCategoryId(int categoryId)
        {
            return _productDal.GetList(p => p.CategoryId == categoryId || categoryId== 0);
        }
        public Product GetById(int productId)
        {
            return _productDal.Get(p => p.ProductId == productId);
        }
        public void Update(Product product)
        {
            _productDal.Update(product);
        }
    }

This is my business layer. When I try to write generic, some things are missing, so I don't understand much. Now I want to ask, how should I write the following code, because I'm new, I couldn't do it.

List<Product> products = context.Products.Include(x => x.Photos).ToList();

I can post it anywhere you want.

CodePudding user response:

If I understood you correctly, you want to change

List<Product> products = context.Products.Include(x => x.Photos).ToList()

to something like:

List<T> entities = context.Set<T>().Include(x => x.Photos).ToList()

You can not. Let's say you want to use this generic class for your Category model and your Category model does not have Photos property.

I would suggest to make a generic Repository class for all CRUD operations

public interface IBaseRepository<T> where T : class
{
    Task AddAsync(T entity);
    void Delete(T entity);
    void Update(T entity);
    Task<IEnumerable<T>> GetAllAsync();
    Task<T> FindAsync(Expression<Func<T, bool>> expression);
}

And implementing:

public class BaseRepository<T> : IBaseRepository<T> where T : class
{
    protected readonly AppDbContext _context;

    private DbSet<T> _dbSet;

    public DbSet<T> DbSet => _dbSet ??= _context.Set<T>();

    public BaseRepository(AppDbContext context)
    {
        _context = context;
    }

    public async Task AddAsync(T entity)
    {
        await DbSet.AddAsync(entity);
    }

    public void Delete(T entity)
    {
        DbSet.Remove(entity);
    }

    public void Update(T entity)
    {
        DbSet.Update(entity);
    }

    // here we made vitrual, this gaves us opportunity to override this method 
    public virtual async Task<IEnumerable<T>> GetAllAsync()
    {
        return await DbSet.ToListAsync();
    }

    public virtual async Task<T> FindAsync(Expression<Func<T, bool>> expression)
    {
        return await DbSet.Where(expression).FirstOrDefaultAsync();
    }
}

Your Product Repository:

public class ProductRepository : BaseRepository<Product>
{
    public ProductRepository(AppDbContext context) : base(context)
    {
    }

    public async override Task<IEnumerable<Product>> GetAllAsync()
    {
        return await DbSet.Include(p => p.Photos).ToListAsync();
    }
}
  • Related