Подтвердить что ты не робот

Репозиторий Factory Класс

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 класс репозитория и реализовать что-то вроде

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

Ответ 1

Простейшая из фабрик просто требует, чтобы ваши типы, полученные из 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>();

Ответ 2

Чтобы что-то вернуть, вам нужно написать класс, который реализует 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;
    }
}

Ответ 3

Вы можете обойтись без enum. Вам нужен либо общий тип репозитория, либо различные типы репозиториев, реализующие IRepository<T>. Если вы используете общий репозиторий, вы можете реализовать factory, выполнив что-то в строках:

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

Ответ 4

Я бы рекомендовал использовать для этого контейнер Inversion of Control (IoC). В Factory (или вы даже можете перейти прямо к контейнеру 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()
     } 
   }
}

или еще лучше. Просто используйте общий метод в factory

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


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