2012-05-11 4 views
0

У меня есть настройки хранилища, как показано ниже.Использование универсального репозитория интерфейса

interface IRepository<T> where T : DataRow 
{ 
    T Get(int key); 
} 

interface ICartonRepository : IRepository<CartonDataRow> 
{ 

} 

class CartonRepository : ICartonRepository 
{ 
    public CartonDataRow Get(int key) 
    { 

    } 
} 

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

IRepository<DataRow> repository; 
switch (rowType) 
{ 
    case Carton: 
    repository = new CartonRepository(); 
    break; 
    case Pack: 
    repository = new PackRepository(); 
    break; 
} 

Есть ли способ, которым я могу это достичь?

+0

То, что у вас есть, прекрасно в теории, если у вас есть правильный способ определения того, как конкретный репозиторий сопоставляется с «rowType», с которым вы столкнулись. Есть ли что-то конкретное, что не работает? –

+2

Не уверен, что я понимаю намерение - если вы объявляете репозиторий как IRepository , тогда вызовы его метода Get возвращают тип DataRow типа компиляции, а не один из его подклассов. В таком сценарии вы можете просто отказаться от родового из IRepository и вернуть его DataRow :) –

ответ

0

Для C# 3.5 Вы должны добавить следующее:

public interface IRepository { 
    DataRow Get(int key); 
} 

public abstract class Repository<T> : IRepository<T>, IRepository 
    where T : DataRow 
{ 
    public abstract T Get(int key); 

    DataRow IRepository.Get(int key) { 
     return this.Get(key); 
    } 
} 

Затем измените CartonRepository на class CartonRepository : Repository<CartonDataRow> (я не думаю, что вам нужно ICartonRepository, но вы можете использовать его, если хотите). Затем

IRepository repository; 
switch (rowType) 
{ 
    case Carton: 
    repository = new CartonRepository(); 
    break; 
    case Pack: 
    repository = new PackRepository(); 
    break; 
} 
0
interface IRepository<out T> where T : DataRow 
{ 
    T Get(int key); 
} 

Для этого требуется C# 4.0.

+0

Есть ли решение 3.5? – JKF

+0

Единственной частью этого, которая требует .NET4.0, является параметр «out», объявляющий typeparam «T» как ковариантный. Это не обязательно для решения для создания общей реализации репозитория. –

0

Вам требуется какой-то Factory pattern.

После логика должна идти в класс Factory

class RepositoryFactory 
{ 
    IRepository<T> Get(rowType) 
    { 
     IRepository<T> repository = default(IRepository<T>); 
     switch (rowType) 
     { 
     case Carton: 
      repository = new CartonRepository(); 
      break; 
     case Pack: 
      repository = new PackRepository(); 
      break; 
     } 

     return repository; 
    } 
} 

Вы можете дополнительно улучшить Получ с помощью Dependency Injection или основанный на сохранении всех репозиториев в dictionary.

+0

+1 для названия фабрики отдельно => очень полезные знания, и многие школы не упоминают об этом –

Смежные вопросы