views:

92

answers:

3

I have a base repository class which contains all the common repository methods (as generic):

public abstract class BaseRepository<T, IdType> : IBaseRepository<T, IdType>

My repositories from this base e.g.:

public class UserRepository : BaseRepository<User, int>, IUserRepository

I also have a base controller class containing common actions, and inherit from this in controllers. The repository is injected into this by DI. E.g.

public class UserController : BaseController<User>
{
        private readonly IUserRepository userRepository;

        public UserController (IUserRepository userRepository)
        {
            this.userRepository= userRepository;
        }

My question is this: The base controller needs to be able to access the repository methods that are defined in the base repository. However I'm passing in via DI a different repository type for each controller (even though they all inherrit from the base repository). How can the base controller somehow access the repository that is passed in (regardless of what type it is), so that it can access the common base methods?

+1  A: 

You can hold a reference for BaseReposiroty in BaseController

public class BaseController <T, IdType>
{
    ...
    ...
    protected BaseRepository<T, IdType> Reposirory
    {
        { get; set; }
    }
    ...
    ...
}
Itay
Hi Itay, that's what I'm trying to do - but how do I get this reference when I'm passing in a subclassed repository?
UpTheCreek
I do not understand your question
Itay
Ah, sorry - was having a gump moment. Got it, thanks.
UpTheCreek
+1  A: 

It all your repositories will be derived from IBaseRepository<T,IdType>, then have:

interface IUserRepository : IBaseRepository<User,int> {...}

Now any reference to a IUserRepository will know about the IBaseRepository<> members, without having to mention concrete types like the UserRepository class or BaseRepository<> class.

Marc Gravell
Hi Marc, yes, I didn't show it in my post, but I'm already inherriting IUserRepository from IBaseRepository<User,int>.
UpTheCreek
@UpTheCreek - if you mean that you need methods from `BaseRepository<>` (the class), then you've broken the point of abstracting to the interface... if you mean the `IBaseRepository<>` interface, it should already work.
Marc Gravell
+1  A: 

Here's one way to do it..

public abstract class BaseController<TEntity, TRepository, TIdType>
    where TEntity : class, new()
    where TRepository : IBaseRepository<TEntity, TIdType>
{
    protected TRepository Repository = RepositiryFactory.GetRepository<TEntity, TRepository>();

    public IList<TEntity> GetAll()
    {
        return Repository.GetAll().ToList();
    }
    public IList<TEntity> GetAll(string sortExpression)
    {
        return Repository.GetAll(sortExpression).ToList();
    }
    public int GetCount()
    {
        return Repository.GetAll().Count();
    }
    public IList<TEntity> GetAll(int startRowIndex, int maximumRows)
    {
        var results = Repository.GetAll().Skip(startRowIndex).Take(maximumRows);
        return results.ToList();
    }
    public IList<TEntity> GetAll(string sortExpression, int startRowIndex, int maximumRows)
    {
        var results = Repository.GetAll(sortExpression).Skip(startRowIndex).Take(maximumRows);
        return results.ToList();
    }
}
this. __curious_geek