开发者

A Repository Factory Class

开发者 https://www.devze.com 2023-02-03 16:29 出处:网络
public enum Re开发者_如何转开发positoryType { ClinicRepository, MedicationRepository, PatientRepository,
public enum Re开发者_如何转开发positoryType
{
    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);
}

I'm trying to create a RepositoryFactory class and I copied what I've done so far. Could anyone please help me to figure this out ? I'm stuck ! Thanks in advance

edit :

I want something like this at the end. Is it possible to make 1 Repository class and implement something like

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


The simplest of factories just requires that your types derived from IRepository have parameterless constructors.

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

If you require specific constructors for a given repository type, you can specify the objects as an object array and create them using CreateInstance

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

To use either of these, you just need to say

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


To have something to return, you need to write a class that implements IRepository<T>.

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

    // and so on...
}

It appears there are four broad types (ClinicRepository, MedicationRepository, etc.) - are they very different in how they "store" things? If so, make a separate class for each one. Otherwise use the same class with some fields to control its behaviour.

Update

Based on your edits and comments, you have a repository that is really some operations on a table. The only thing that really varies is which table it wraps around. But the table is a member of a data context. So you could defer the choice of table to a derived class.

This would be the base class:

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
}

A derived class would only have to specify how to select a table from the context:

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


You can do without the enum. You either need a generic repository type, or different repository types implementing IRepository<T>. If you use a generic repository, you can implement the factory by doing something along the lines of:

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


I would recommend that you use an Inversion of Control (IoC) container for this. In the Factory (or you could even go straight to the IoC container), could get the type.

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

or better yet Just use a generic method in your factory

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


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

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号