Шаблон репозитория для нескольких поставщиков данных / ORM? - PullRequest
4 голосов
/ 08 июля 2011

Скажем так, у меня есть следующие модели данных:

public class Account
{
   public string Username { get; set; }
   public string Password { get; set; }
}

public class Configuration
{
   public string Key { get; set; }
   public string Value { get; set; }
}

На данный момент каждая из них имеет свой собственный репозиторий для доступа к данным и использует структуру сущностей в качестве своей единицы работы / DbContext.Я планирую вытащить часть конфигурации из фрейма сущности и использовать Redis или Memcached в качестве доступа к данным.Я мог бы даже переключить EF на NHibernate или вообще не использовать ORM, и я мог бы переключить базу данных на MongoDB или CouchDB.

Какой хороший способ сделать это?Быть в неведении обо всех этих вещах нижнего уровня в моей бизнес-логике?Какую модель использовать?Возможно ли, или это просто плохие вещи для таких изменений?

Спасибо:)

Ответы [ 2 ]

4 голосов
/ 08 июля 2011

Как указывалось в предыдущем посте, вы должны идти «путем интерфейса».Я лично не внедряю репозиторий непосредственно для каждой формы, но я использую небольшой вариант.Используя ваш пример ...

public interface IAccountRepository
{
  Account Get(int id);
  void Delete(int id);
  ...other method...
}

, вы создаете свой репозиторий

public class AccountRepository : IAccountRepository
{
   private readonly IUnitofWork unitofWork;

   public AccountRepository(IUnitofWork unitofWork)
   {
      this.unitofWork = unitofWork;
   }

   //Implement interface method
   public Account Get(int id)
   {
      //some logic or just the call to the unit of work
      return unitofWork.Get(id);
   }
}

Я доволен этим решением, потому что в итоге я получаю только один репозиторий, который используется в 90% случаев.linq для запроса, поэтому мне не нужно писать sql для каждой единицы работы, и каждый раз, когда мне нужно написать «GetAllProducts» с подкачкой страниц, мне не нужно писать один и тот же код (и тесты) для каждой единицы работы,но только для моего хранилища.Это простой пример, очевидно, поэтому я надеюсь, что вы поняли идею.Вы можете создать RepositoryBase, который реализует метод Find () или Query (), который использует linq.Затем с вашим Виндзорским замком или кем-то еще, или как вы можете ввести ту единицу работы, которую вы предпочитаете.Надеюсь, это поможет.

Обновление: пример моего UnitofWorkBase, реализующего nhibernate, выглядит примерно так:

public class NHUnitofWork<T> : IUnitofWork<T> where T : EntityBase
{
protected INHSessionBuilder SessionBuilder { get; private set; }

public NHPersistorBase(INHSessionBuilder sessionBuilder)
{
  SessionBuilder = sessionBuilder;
}

public T Get(int id)
{
  T result = null;
  ISession session = SessionBuilder.GetSession();
  using (ITransaction transaction = session.BeginTransaction(System.Data.IsolationLevel.ReadCommitted))
  {
    try
    {
      result = (T)session.Get(typeof(T), id);
      transaction.Commit();
    }
    finally
    {
      if (transaction.IsActive)
        transaction.Rollback();
    }
  }
  return result;
}
public IQueryable<T> Find()
{
  return SessionBuilder.GetSession().Query<T>();
}

}

1 голос
/ 08 июля 2011

Используйте интерфейс.

public class IAccountRespository
{
   public Account LoadAccountByUsername(String Username);
   public void DeleteAccont(Account a);
   public void SaveAccont(Account a);
   .
   .
   .
   ...more methods
}

, затем вы реализуете этот интерфейс для каждого объекта доступа к данным (например, mongdb и т. Д.).

В коде бизнес-логики вы используете толькоинтерфейс, а не фактический объект.

Я использую фабричный шаблон для создания объектов доступа к данным, но вы можете использовать каждый шаблон IoC.

...