0
votes

I've built a generic repository interface off which hang a number of entity specific repository interfaces. Mirroring this structure are a number of concrete repository classes.

I'm getting the following error in my base Repository class:

Error location

Type 'TEntity' doesn't match expected type '???'.
Method 'GetAll' cannot implement method from interface '...IRepository<TEntity, TIdentity>'. Return type should be 'System.Collections.Generic.List<???>'.

The minified interface/class structure is as follows:

IRepository:

public interface IRepository<TEntity, in TIdentity> where TEntity : IEntity<TIdentity>
{
    ...
    List<TEntity> GetAll();
    ...
}

Repository:

internal class Repository<TEntity, TIdentity> : IRepository<TEntity, TIdentity>
        where TEntity : class, IEntity<TIdentity>
{
    ...
    protected DbSet<TEntity> Set => _set ?? (_set = _context.Set<TEntity>());

    public List<TEntity> GetAll()
    {
        return Set.ToList();
    }
    ...
}

IRoleRepository:

public interface IRoleRepository : IRepository<Role, Guid>
{
    ...
    Role FindByName(string roleName);
    ...
}

RoleRepository:

internal class RoleRepository : Repository<Role, Guid>, IRoleRepository
{
    ...
    public Role FindByName(string roleName)
    {
        return Set.FirstOrDefault(x => x.Name == roleName);
    }
    ...
}

This has a knock on effect in my consuming classes where doing a RoleRepository.GetAll() returns a List<???> rather than a List<Role> as I expected.

Edit - Entity definitions...

IEntity:

public interface IEntity<T>
{
    T Id { get; set; }
    byte[] Version { get; set; }
}

Entity:

public abstract class Entity<T> : IEntity<T>
{
    public T Id { get; set; }
    public byte[] Version { get; set; }
}

Role:

public class Role : Entity<Guid>
{
    private ICollection<User> _users;
    public string Name { get; set; }
    public ICollection<User> Users
    {
        get { return _users ?? (_users = new List<User>()); }
        set { _users = value; }
    }
}
1
I think it should be Set.ToList<TEntity>(); - vendettamit
Thanks, tried that but it doesn't resolve the error. Also ReSharper tells me Type argument specification is redundant. - Chris Pickford
Is your TEntity implementing all interfaces from where statement? I think TEntity is not implementing IEntity<TIdentity> as TEntity is EF type. Try remove where from that repository. - madoxdev

1 Answers

0
votes

It looks like your TEntity class is not implementing that interface: IEntity<TIdentity>

Depends if your are using CodeFirst at EntityFramework or ModelFirst you have other options to go with:

ModelFirst: you can use Model.tt file to specify implementation of interfaces you need.

CodeFirst: just implement that interface in the model class.

Third option is just get rid of that where TEntity : IEntity<TIdentity> only if your are not using anything from that interface of course.