简体   繁体   中英

Can an interface require a base class to be implemented?

I have an abstract BaseRepository which handles basic CRUD operations.

public abstract class BaseRepository
{
    protected readonly IDbContextFactory<DbContext> _dbContextFactory;

    public BaseRepository(IDbContextFactory<TrinityDbContext> dbContextFactory)
    {
        _dbContextFactory = dbContextFactory;
    }
}

public abstract class BaseRepository<T> : BaseRepository where T : class, IUniqueIdentifier
{
    public BaseRepository(IDbContextFactory<TrinityDbContext> dbContextFactory) : base(dbContextFactory) { }
}

I created an abstract RepoServiceBase to add those CRUD operations to my services.

public abstract class RepoServiceBase<T> where T : class, IUniqueIdentifier
{
    private readonly BaseRepository<T> _repo;

    public RepoServiceBase(BaseRepository<T> repo)
    {
        _repo = repo;
    }
}

But when constructing the service I get the following error: Cannot convert from IProductRepository to BaseRepository

public class ProductService : RepoServiceBase<Product>, IProductService
{
    public ProductService(IProductRepository repo) : base(repo) { }
}

Is there a way to require IProductRepository to implement BaseRepository?

Is there a way to require IProductService to implement BaseRepository?

No, you can't do this.

But you can create additional interfaces to handle that.

Create interfaces for base repositores:

public interface IBaseRepository
{
    // methods
}

public interface IBaseRepository<T> : IBaseRepository
{
    // methods
}

Implement these interfaces by base repositories:

public abstract class BaseRepository : IBaseRepository
{
    protected readonly IDbContextFactory<DbContext> _dbContextFactory;

    public BaseRepository(IDbContextFactory<TrinityDbContext> dbContextFactory)
    {
        _dbContextFactory = dbContextFactory;
    }
}

public abstract class BaseRepository<T> : BaseRepository, IBaseRepository<T> where T : class, IUniqueIdentifier
{
    public BaseRepository(IDbContextFactory<TrinityDbContext> dbContextFactory) : base(dbContextFactory) { }
}

Now your product repository stuff should look like this:

public interface IProductRepository : IBaseRepository<Product>
{
    // methods
}

public class ProductRepository : BaseRepository<Product>, IProductRepository
{
    // implementation
}

Change RepoServiceBase :

public abstract class RepoServiceBase<T> where T : class, IUniqueIdentifier
{
    private readonly IBaseRepository<T> _repo;

    public RepoServiceBase(IBaseRepository<T> repo)
    {
        _repo = repo;
    }
}

You can ignore IBaseRepository interface (non-generic one) as you expect only generic version in constructor params.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM