Конкретные общие интерфейсы - PullRequest
3 голосов
/ 02 марта 2010

Я рефакторинг всех своих интерфейсов репозитория различных типов. Большинство из них содержат очень похожие методы, такие как Add, Update, но некоторые имеют методы, которые имеют смысл только для определенного типа. Это вопрос передового опыта.

Я подумал об использовании дженериков, чтобы исправить положение.

 public interface IRepository<T>
 {
      T Get(int id);
      void Add(T x);
 }

Но теперь по конкретным методам. Я мог бы, конечно, "подкласс" интерфейс, но тогда я не лучше, чем раньше. Я хотел бы иметь такой код:

 IUserRepository<User> users;

Один аккуратный способ был бы, если бы я мог иметь несколько ограничений, таких как:

 public partial interface IRepository<T>
 {
      T Get(int id);
      void Add(T x);
 }

 public partial interface IRepository<T> where T: User
 {
      T Get(Guid id);
 }

 public partial interface IRepository<T> where T: Order
 {
      T Get(string hash);
 }

Но компилятор жалуется на конфликтующее наследование. Другим способом были бы ограничения на методы:

 public partial interface IRepository<T>
 {
      T Get(int id);
      void Add(T x);

      T Get(Guid id) where T: User;
      T Get(string hash) where T: Order;
 }

Но это не совсем так, как эта работа. Конечно, компилятор не понимает моих намерений и хочет определить тип метода.

Сейчас у меня просто есть методы, которые выдают NotImplemented. Некрасиво.

Я ищу решение, которое заставит меня пнуть себя.

Ответы [ 2 ]

6 голосов
/ 02 марта 2010
public interface IRepository<TEntity, TId>
 {
      TEntity Get(TId id);
      void Add(T x);
 }

public class UserRepository : IRepository<User, Guid>
{
    public User Get( Guid id ) 
    {
        // ...
    }

    public void Add( User entity) 
    {
        // ...
    }
}

public class OrderRepository : IRepository<Order, string> 
{
    //...
}
2 голосов
/ 02 марта 2010

Вот мои мысли по похожему вопросу:

Преимущество создания общего хранилища по сравнению с конкретным хранилищем для каждого объекта?

Суть в том, что домены часто не могут быть обобщены, и существует другой подход. Я привожу пример использования доменных интерфейсов, но с обобщенным базовым классом.

...