存储库工厂类

时间:2011-01-12 14:09:15

标签: c# repository

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类,我复制了迄今为止我所做的事情。有人可以帮我解决这个问题吗?我被卡住了! 提前致谢

编辑:

最后我想要这样的东西。是否可以制作1个Repository类并实现类似

的内容

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

4 个答案:

答案 0 :(得分:12)

最简单的工厂只需要从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>();

答案 1 :(得分:6)

要返回某些内容,您需要编写一个实现IRepository<T>的类。

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

    // and so on...
}

看来有四种广泛的类型(ClinicRepository,MedicationRepository等) - 它们在“存储”事物方面有很大不同吗?如果是这样,请为每个人单独创建一个类。否则,使用相同的类和一些字段来控制其行为。

<强>更新

根据您的编辑和注释,您有一个存储库,它实际上是对表的一些操作。唯一真正变化的是它包裹的桌子。但该表是数据上下文的成员。因此,您可以将表的选择推迟到派生类。

这将是基类:

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

答案 2 :(得分:0)

你可以不用enum。您需要通用存储库类型或实现IRepository<T>的不同存储库类型。如果您使用通用存储库,则可以通过执行以下操作来实现工厂:

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

答案 3 :(得分:0)

我建议您使用Inversion of Control(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>();