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

Intento crear una clase RepositoryFactory y copié lo que he hecho hasta ahora. ¿Alguien podría ayudarme a resolver esto? Estoy atascado ! Gracias de antemanoA Repository Factory Class

edición:

Quiero algo como esto al final. ¿Es posible crear 1 clase de repositorio e implementar algo como

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

Respuesta

13

La más simple de las fábricas simplemente requiere que sus tipos derivados de IRepository tienen constructores sin parámetros.

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

Si necesita constructores específicos para un tipo determinado repositorio, puede especificar los objetos como un conjunto de objetos y crearlas usando CreateInstance

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

Para utilizar cualquiera de estos, sólo tiene que decir

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

¿Cuál es la ventaja de utilizar una fábrica de repositorios? – Oskar

7

tener algo para volver, tiene que escribir una clase que implementa IRepository<T>.

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

    // and so on... 
} 

Parece que hay cuatro tipos generales (ClinicRepository, MedicationRepository, etc.) - ¿Son muy diferentes en la forma en que las cosas "almacenar"? Si es así, crea una clase separada para cada uno. De lo contrario, use la misma clase con algunos campos para controlar su comportamiento.

actualización

Sobre la base de los cambios y los comentarios hay un repositorio que es realmente algunas operaciones sobre una mesa. Lo único que realmente varía es en qué mesa se envuelve. Pero la tabla es un miembro de un contexto de datos. Entonces, podrías diferir la elección de la tabla a una clase derivada.

Ésta sería la clase base:

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 
} 

Una clase derivada sólo se tendría que especificar cómo seleccionar una tabla a partir del contexto:

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

edito la pregunta. Tengo un contexto de datos linqtosql. ¿Es factible? – Kubi

+0

+1 para la actualización. Gracias – Kubi

+0

@Kubi: según la respuesta que haya aceptado, debo decir que no tengo ni idea de cuál fue su pregunta en realidad. En su edición, solicitó obtener "dc.THATOBJECT.insertonsubmit (item)". De eso trata mi actualización. –

0

Puede prescindir de la enum. Necesita un tipo de repositorio genérico o diferentes tipos de repositorio implementando IRepository<T>. Si utiliza un repositorio genérico, se puede implementar la fábrica haciendo algo en la línea de:

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

Yo recomendaría que utilice un contenedor de Inversión de control (IoC) para esto. En la fábrica (o incluso podría ir directamente al contenedor IoC), podría obtener el tipo.

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

o mejor aún, sólo tiene que utilizar un método genérico en su fábrica de

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


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