2011-01-12 13 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); 
} 

Próbuję utworzyć klasę RepositoryFactory i skopiowałem to, co zrobiłem do tej pory. Czy ktokolwiek może mi pomóc, aby to rozwiązać? Utknąłem! góry dziękiFabryka Repozytorium Klasa

edit:

chcę coś takiego na końcu. Czy można wykonać 1 klasę Repozytorium i zaimplementować coś w rodzaju:

dc.THATOBJECT.insertonsubmit (element)?

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

Odpowiedz

13

Najprostszym fabryk po prostu wymaga, aby Twoje typy pochodzące od IRepository mieć konstruktorów bez parametrów.

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

Jeśli wymagają specyficznych konstruktorów dla danego typu repozytorium, można określić obiekty jako tablicę obiektów i tworzyć je za pomocą CreateInstance

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

Aby skorzystać z jednej z nich, wystarczy powiedzieć

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

Jakie są zalety korzystania z fabryki repozytoriów? – Oskar

7

mieć coś do powrotu, trzeba napisać klasy, która implementuje IRepository<T>.

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

    // and so on... 
} 

Wydaje istnieją cztery podstawowe typy (ClinicRepository, MedicationRepository, itd.) - są one bardzo różne w jaki sposób rzeczy „Store”? Jeśli tak, utwórz osobną klasę dla każdej z nich. W przeciwnym razie użyj tej samej klasy w niektórych polach, aby kontrolować jej zachowanie.

Aktualizacja

podstawie Twoich zmian i komentarzy, masz repozytorium, które jest naprawdę niektóre operacje na stole. Jedyną rzeczą, która naprawdę się różni, jest to, który stół otacza. Ale tabela jest elementem kontekstu danych. Więc możesz odroczyć wybór tabeli do klasy pochodnej.

Byłby to klasa bazowa:

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 
} 

klasy pochodnej musiałaby jedynie określić, jak wybrać stolik z kontekstu:

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

edytować pytanie. Mam kontekst danych linqtosql. Czy to jest wykonalne? – Kubi

+0

+1 dla aktualizacji. Dzięki – Kubi

+0

@Kubi - na podstawie odpowiedzi, którą zaakceptowałeś, muszę powiedzieć, że nie mam pojęcia, co właściwie było Twoim pytaniem! Poprosiłeś w swojej edycji o osiągnięciu "dc.THATOBJECT.insertonsubmit (item)" To jest moja aktualizacja. –

0

Można to zrobić bez enum. Potrzebny jest ogólny typ repozytorium lub różne typy repozytoriów implementujące IRepository<T>. Jeśli używasz rodzajowe repozytorium, można zaimplementować fabryki robiąc coś wzdłuż linii:

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

Polecam do tego celu użycie kontenera Inversion of Control (IoC). W fabryce (lub możesz nawet przejść od razu do kontenera IoC), można uzyskać ten typ.

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() 
    } 
    } 
} 

albo jeszcze lepiej po prostu użyć metody rodzajowe w swojej fabryce

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


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