Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# .NET Design Pattern issue

I'm trying to implement the best code re-usability. The problem is that I can't access the base method located in the Base Abstract class form the Main Program through the repository.

If you go through the example below you will see a sample code of my situation.

So my question is how can I access methods located in the base abstract class from the main program.

Classes/Interfaces

public abstract class BaseEntity
{
    public override abstract String ToString();
}

public abstract class BaseClass<T> where T : BaseEntity
{
    public T GetById(int id)
    {
        //Dummy Code
        return new T();
        //
    }
}

public interface IFooRepository
{
    IList<Foo> GetOrderedObjects();
}

public interface FooRepository : BaseClass<Foo>, IFooRepository
{
    public IList<Foo> GetOrderedObjects()
    {
        //GetById method is accessible from the repository - Fine
        var obj = this.GetById(5);

        //Dummy Code
        return new List<Foo>();
        //
    }
}

//Main App

public class void Main()
{
    private IFooRepository _fooRepository;

    public void ProgramStartsHere()
    {
         //This is ok.
         var list = _fooRepository.GetOrderedObjects();

         //Problem is here - GetById method is not accessible from the main program through the FooRepository
         var obj = _fooRepository.GetById(10);
    }
}
like image 466
user1382086 Avatar asked Dec 16 '22 00:12

user1382086


2 Answers

GetById isn't defined in the interface

I would make an

public interface IBaseRepository<T> where T : BaseEntitiy {
 T GetById<T>(int id);
}

Then BaseClass implements IBaseRepository<T>

and IFooRepository inherits from IBaseRepository<Foo>

EDIT :

A full example, similar to @Olivier J-D one, with idea (maybe wrong), that GetOrderedObject may be same for all your entities.

public abstract class BaseEntity
{
    public override abstract String ToString();
}

//all generic methods
public interface IRepositoryBase<T>
    where T : BaseEntity, new()
{
    T GetById(int id);
    IList<T> GetOrderedObjects();

}

//all methods specific to foo, which can't be in a generic class
public interface IFooRepository :IRepositoryBase<Foo>
{
    void Update(Foo model);
}

//implementation of generic methods
public abstract class BaseClass<T> : IRepositoryBase<T>
    where T : BaseEntity, new() // ===> Add new() constraint here
{
    public T GetById(int id)
    {
        return new T();
    }
    public IList<T> GetOrderedObjects() {
        var obj = this.GetById(5);

        //Dummy Code
        return new List<Foo>();
        //
    }
}

//implementation of Foo specific methods
public class FooRepository : BaseClass<Foo>, IFooRepository
{
    public void Update(Foo model) {
    //bla bla
    }
}
like image 160
Raphaël Althaus Avatar answered Dec 28 '22 11:12

Raphaël Althaus


Add a new Interface which declares the GetById method and let IFooRepository and BaseClass<T> inherit from it. You will have to add a generic type parameter to IFooRepository as well. (I renamed IFooRepository to IRepository<T>, since it is generic now.)

public abstract class BaseEntity
{
    public override abstract String ToString();
}

public interface IRetriever<T>
    where T : BaseEntity, new()
{
    T GetById(int id);
}

public interface IRepository<T> : IRetriever<T>
    where T : BaseEntity, new()
{
    IList<T> GetOrderedObjects();
}

public abstract class BaseClass<T> : IRetriever<T>
    where T : BaseEntity, new() // ===> Add new() constraint here
{
    public T GetById(int id)
    {
        return new T();
    }
}

public class FooRepository : BaseClass<Foo>, IRepository<Foo>
{
    public IList<Foo> GetOrderedObjects()
    {
        var obj = this.GetById(5);
        return new List<Foo>();
    }
}

This will work fine then

IRepository<Foo> _fooRepository = new FooRepository();
var list = _fooRepository.GetOrderedObjects();
var obj = _fooRepository.GetById(10);
like image 37
Olivier Jacot-Descombes Avatar answered Dec 28 '22 10:12

Olivier Jacot-Descombes