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

Ich versuche, eine RepositoryFactory-Klasse zu erstellen, und ich habe kopiert, was ich bisher getan habe. Könnte mir bitte jemand helfen, das herauszufinden? Ich stecke fest ! Vielen Dank im VorausEin Repository Factory-Klasse

edit:

Ich mag so etwas wie dies am Ende. Ist es möglich, 1 Repository-Klasse zu erstellen und so etwas wie

zu implementieren 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(); 
     } 
    } 

Antwort

13

Die einfachste Fabriken erfordert nur, dass Ihre Typen abgeleitet von IRepository parameterlos Konstrukteure haben.

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

Wenn Sie bestimmte Konstrukteuren für eine bestimmte Repository-Typ erfordern, können Sie die Objekte als Objektarray angeben können, und erstellen Sie sie mit CreateInstance

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

entweder von diesen zu verwenden, müssen Sie nur sagen,

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

Was sind die Vorteile einer Repository Factory? – Oskar

7

etwas zu haben, zurückzukehren, müssen Sie eine Klasse schreiben, die IRepository<T> implementiert.

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

    // and so on... 
} 

Es scheint, gibt es vier große Arten (ClinicRepository, MedicationRepository, etc.) - sie sind sehr verschieden, wie sie "store" Dinge? Wenn ja, machen Sie für jede eine eigene Klasse. Andernfalls verwenden Sie dieselbe Klasse mit einigen Feldern, um ihr Verhalten zu steuern.

aktualisieren

Basierend auf Ihre Änderungen und Kommentare, haben Sie ein Repository, das wirklich einige Operationen auf einem Tisch ist. Das einzige, was wirklich variiert, ist, um welchen Tisch es sich handelt. Die Tabelle ist jedoch ein Mitglied eines Datenkontextes. Sie können also die Wahl der Tabelle auf eine abgeleitete Klasse verschieben.

Dies würde die Basisklasse sein:

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 
} 

Eine abgeleitete Klasse müßte nur angeben, wie eine Tabelle aus dem Kontext wählen:

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

ich die Frage bearbeiten. Ich habe einen Linqtosql Datenkontext. Ist es machbar? – Kubi

+0

+1 für das Update. Danke – Kubi

+0

@Kubi - basierend auf der Antwort, die Sie akzeptiert haben, muss ich sagen, habe keine Ahnung, was deine Frage war! Du hast in deinem Edit gefragt, ob du "dc.THATOBJECT.insertonsubmit (item)" erreichen kannst. Darum geht es in meinem Update. –

0

Sie ohne enum tun können. Sie benötigen entweder einen generischen Repository-Typ oder verschiedene Repository-Typen, die IRepository<T> implementieren. Wenn Sie eine generische Repository verwenden, können Sie die Fabrik, indem Sie etwas entlang der Linien von implementieren:

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

Ich würde empfehlen, dass Sie einen Inversion of Control (IoC) Container dafür verwenden. In der Factory (oder man könnte sogar direkt in den IoC-Container gehen), könnte man den Typ bekommen.

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

oder besser noch nur eine generische Methode in der Fabrik verwendet

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


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