2011-01-12 3 views
12
public enum RepositoryType 
{ 
    ClinicRepository, 
    MedicationRepository, 
    PatientRepository, 
    TreatmentRepository 
} 

public class ObjectFactory<T> 
{ 
    public static IRepository<T> GetRepositoryInstance(RepositoryType type) 
    { 
     switch (type) 
     { 
      case RepositoryType.ClinicRepository: 
       return new what ?; 

      default: 
       return what ? 
     } 
    } 
} 

public interface IRepository<T> 
{ 
    void Add(T item); 
    void Remove(int id); 
    void Update(T item); 
    IList<T> GetAll(); 
    T GetItemById(int id); 
} 

Я пытаюсь создать класс RepositoryFactory, и я скопировал то, что я сделал до сих пор. Может ли кто-нибудь помочь мне разобраться в этом? Я застрял ! Заранее спасибоA Repository Factory Class

редактировать:

Я хочу что-то вроде этого в конце. Можно ли сделать 1 класс репозитория и реализовать что-то вроде

dc.THATOBJECT.insertonsubmit (item)?

public class TreatmentRepository : IRepository<Treatment> 
{ 
    public void Add(Treatment item) 
    { 
     using (PatientsDataContext dc = new PatientsDataContext()) 
     { 
      dc.Treatments.InsertOnSubmit(item); 
      dc.SubmitChanges(); 
     } 
    } 

ответ

13

Простейших заводов просто требует, чтобы ваши типов, полученных из IRepository имеют конструктор без параметров.

public class ObjectFactory { 
    public static TRepository GetRepositoryInstance<T, TRepository>() 
     where TRepository : IRepository<T>, new() { 
     return new TRepository(); 
    } 
} 

Если требуются специальные конструкторы для данного типа хранилища, вы можете указать объекты как массив объектов и создать их с помощью CreateInstance

public class ObjectFactory { 
    public static TRepository GetRepositoryInstance<T, TRepository>(
     params object[] args) 
     where TRepository : IRepository<T> { 
     return (TRepository)Activator.CreateInstance(typeof(TRepository), args); 
    } 
} 

Чтобы использовать любой из них, вы просто должны сказать

var treatmentRepo = 
    ObjectFactory.GetRepositoryInstance<Treatment, TreatmentRepository>(); 
+0

В чем преимущества использования фабрики репозитория? – Oskar

7

Чтобы иметь что-то, чтобы вернуться, вам нужно написать класс, который реализует IRepository<T>.

public class SomeKindOfRepository<T> : IRepository<T> 
{ 
    public void Add(T item) 
    { 
    } 

    // and so on... 
} 

Оказывается существует четыре основных типа (ClinicRepository, MedicationRepository и т.д.) - они очень разные, как они «магазин» вещи? Если да, сделайте отдельный класс для каждого из них. В противном случае используйте один класс с некоторыми полями для управления его поведением.

Update

на основе ваших правок и комментариев, у вас есть хранилище, которое на самом деле некоторые операции на столе. Единственное, что действительно меняется, - это та таблица, которую она обертывает. Но таблица является членом контекста данных. Таким образом, вы можете отложить выбор таблицы до производного класса.

Это будет базовый класс:

public class GeneralRepository<TEntity, TContext> : IRepository<TEntity> 
{ 
    protected abstract Table<TEntity> GetTable(TContext dc); 

    public void Add(Treatment item) 
    { 
     using (TContext dc = new TContext()) 
     { 
      GetTable(dc).InsertOnSubmit(item); 
      dc.SubmitChanges(); 
     } 
    } 

    // and so on for other methods 
} 

Производный класс должен только указать, как выбрать таблицу из контекста:

public class TreatmentsRepository : GeneralRepository<Treatment, PatientsDataContext> 
{ 
    protected override Table<Treatment> GetTable(PatientsDataContext dc) 
    { 
     return dc.Treatments; 
    } 
} 
+0

отредактировать вопрос. У меня есть контекст данных linqtosql. Это выполнимо? – Kubi

+0

+1 для обновления. Спасибо – Kubi

+0

@ Куби - на основании ответа, который вы приняли, я должен сказать, не знаю, каков ваш вопрос на самом деле! Вы спросили в своем правлении о достижении «dc.THATOBJECT.insertonsubmit (item)« Это то, что касается моего обновления. –

0

Вы можете обойтись без enum. Вам нужен либо общий тип репозитория, либо различные типы репозиториев, реализующие IRepository<T>. Если вы используете общий репозиторий, вы можете реализовать завод, делая что-то вдоль линий:

public class ObjectFactory<T> 
{ 
    public static IRepository<T> GetRepositoryInstance() 
    { 
     return new Repository<T>(); 
    } 
} 
0

Я бы порекомендовал вам использовать для этого контейнер инверсии управления (IoC). На фабрике (или вы даже можете перейти прямо к контейнеру IoC), можно получить тип.

public interface IClinicRepository : IRepository<Clinic> {} 


public class ObjectFactory 
{ 
    public static IRepository<T> GetRepository(RepositoryType type) 
    { 
    switch (type) 
    { 
     case RepositoryType.ClinicRepository: 
      return container.Resolve<IClinicRepository>() 
      default: 
      throw new NotSupportedException() 
    } 
    } 
} 

или еще лучше просто использовать общий метод в фабрике

public static IRepository<T> GetRepository<T>() 
    { 
     return container.Resolve<T>() 
    } 


    // to call it 
    var repository = ObjectFactory.GetRepository<IClinicRepository>();