简体   繁体   中英

Creating common base class implementing two generic interfaces?

Is there a way to create a base class which implements both of the following two generic interfaces? This base class will then be inherited by "other" classes who can call methods from either of the two interfaces.

public interface IGenericRepositoryOne<E> where E : Entity
{
    void Save(E entity);
    void Save(List<E> entityList);
    E Load(Guid entityId);
}

public interface IGenericRepositoryTwo<D, E> where E : Entity
{
    void Save(D dto);
    void Save(List<D> entityList);
    D Load(Guid entityId);
}

Right now we have two separate Repositories which implement each of the interface separately:

public abstract class RepositoryOne<D, E> : IGenericRepositoryOne<D, E> where E : Entity {...}

public abstract class RepositoryTWO<E> : IGenericRepositoryTwo<E> where E : Entity {...}

And then there are classes which need to inherit either RepositoryOne or RepositoryTwo . It is at these class where I am looking to do some factoring, for example:

public class MessageDataTypeRepository : RepositoryTwo<MyEntityType>
{
    // here when I call the method Load() I want it for RepositoryOne implementation.
}

public class MessageDataTypeRepository : RepositoryOne<MyDTOType, MyEntityType>
{
    // here when I call the method Load() I want it for the RepositoryTwo implementation.
}

You can implement both interfaces, and implement one or both using an Explicit Interface Implementation . This allows you to have different implementations for each interface, if this is a requirement.

If this is not a requirement, simply implementing both should be straightforward, since both interfaces are effectively the same in terms of one generic type:

public class Repository<D,E> : IGenericRepositoryOne<D>, IGenericRepositoryTwo<D,E> 
    where D : Entity
    where E : Entity
{
    void Save(D dto) {}
    void Save(List<D> entityList) {}
    D Load(Guid entityId)
    {
          // Implement...
    }
}

Edit:

In response to your edited question, and your actual goals -

One option here would be to not use inheritance, but composition. By using composition, you could make your "generic repository" class expose a single, meaningful interface, and internally build the appropriate repository. It could then map through the methods to the appropriate repository as needed. This would make your repository effectively an implementation of the Adapter Pattern to wrap either repository with a common interface.

Yes, it's possible and it's called Explicit Interface Implementation

You can implement methods from both interfaces with one method:

public void Save(D entity) { }

or separate implementation:

public void IGenericRepositoryOne.Save(D entity) { }

public void IGenericRepositoryTwo.Save(D entity) { }

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