Home > Blockchain >  C# Generic Repository Implementation
C# Generic Repository Implementation

Time:01-10

I want to have repository which the Generic Implementation of the repository can know about Base Entity Class and access its properties. base entity has all the basic properties of an entity like Id,DateCreated,DateAdded,IsActive ect.
but my problem is that even that all of sub class of Base entity inherit from it, their Repository Class ask for their implementation and don't see that they are derived from a super class that has all the needed properties and I cant reuse the code that I wrote there.

    
    public interface IGenericRepo<T> 
    {
        int Add(T Entity);
        int Delete(T Entity);
    }

    public interface IProductRepository: IGenericRepo<Product>
    {
        Product GetBestselling();
    }

    public class GenericRepo : IGenericRepo<BaseEntity>
    {
        public int Add(BaseEntity Entity)
        {
            Console.WriteLine(Entity.Id);
            return Entity.Id;
        }

        public int Delete(BaseEntity Entity)
        {
            Console.WriteLine(Entity.Id);
            return Entity.Id;
        }
    }

    public class ProductRepo : GenericRepo, IProductRepository
    {
        public Product GetBestselling()
        {
            throw new NotImplementedException();
        }
    }
    public class BaseEntity
    {
        public int Id { get; set; }
        public int DateAdded { get; set; }
    }

    public class Product : BaseEntity
    {
        public string Name { get; set; }
        public string Fname { get; set; }
    }

the code above asks for implementation of IProductRepository, how can I make this work?

CodePudding user response:

You could consider using generic constraints to declare your generic repo:

    public class GenericRepo<T> : IGenericRepo<T> where T : BaseEntity
    {
        public int Add(T Entity) => Entity.Id;
        public int Delete(T Entity) => Entity.Id;
    }
    public class ProductRepo : GenericRepo<Product>, IProductRepository
    {
        public Product GetBestselling() => throw new NotImplementedException();
    }

This lets the base class use the generic parameter as if it is a BaseEntity, but your ProductRepo can be more specific. Note that IGenericRepo<BaseEntity> != IGenericRepo<Product>, to allow implicit conversions, see covariance and contravariance.

CodePudding user response:

    public interface IGenericRepo<T>
{
    int Add(T Entity);
    int Delete(T Entity);
}
public class BaseEntity
{
    public int Id { get; set; }
    public int DateAdded { get; set; }
}

public class Product : BaseEntity
{
    public string Name { get; set; }
    public string Fname { get; set; }
}
public class GenericRepo : IGenericRepo<BaseEntity>
{
    public int Add(BaseEntity Entity)
    {
        Console.WriteLine(Entity.Id);
        return Entity.Id;
    }

    public int Delete(BaseEntity Entity)
    {
        Console.WriteLine(Entity.Id);
        return Entity.Id;
    }
}

public interface IProductRepository 
{
    Product GetBestselling();
}



public class ProductRepo : GenericRepo, IProductRepository
{
    public Product GetBestselling()
    {
        throw new NotImplementedException();
    }
}

This should work without any issues

  •  Tags:  
  • Related