Можно ли установить Datacontext в качестве свойства в репозитории?

StackOverflow https://stackoverflow.com/questions/615960

Вопрос

Есть ли какая-либо потенциальная проблема в установке datacontext в качестве свойства, подобного этому:

хранилище

public Repository()
{ 
    public DataContext dc {get;set;}

    public GetOrders(int id)
       { ...from dc.Orders...}
}

уровень обслуживания:

public GetNewOrders()
   {
       ....
       Repository rep=new Repository();
       using {DataContext dc=new DataContext())
        { 
           rep.dc=dc;
           rep.GetOrders(id);
        }
    }
Это было полезно?

Решение

В DDD вы упускаете из виду общую картину, ссылаясь на конкретные классы.Вы не взаимодействуете между репозиторием и "Уровнем сервисов" в соответствии с лучшими практиками.Если вам необходимо ввести DataContext в репозиторий, я бы рекомендовал провести рефакторинг, чтобы:

public interface IRepository
{
  IList<Orders> GetNewOrders();
}
public Repository : IRepository
{
  private IDataContext _dataContext;
  public Repository(IDataContext dataContext)
  {
    _dataContext = dataContext;
  }
  public IList<Orders> GetNewOrders()
  {
    // perform your actions on _dataContext here
  }
}

Лучшим решением было бы позволить репозиторию обрабатывать DataContext самостоятельно - сохраняя разделение concert действительным, маскируя базовые требования:

public interface IRepository
{
  IList<Orders> GetNewOrders();
}
public Repository : IRepository
{
  private IDataContext _dataContext;
  public Repository(String connectionString)
  {
    _dataContext = new DataContext(connectionString);
  }
  public IList<Orders> GetNewOrders()
  {
    // perform your actions on _dataContext here
  }
} 

Если вам необходимо сохранить контроль над DataContext (или другим классом) самостоятельно (возможно, вы хотите сохранить статическую ссылку или изменить настройки на основе веб-запроса и т.д.), вам нужно будет использовать "Фабрику".

Фабрика выглядела бы примерно так:

public static class DataContextFactory
{
  public static IDataContext GetInstance()
  {
    // return either a static instance, 
    // or threaded instance, a GlobalContext instance
    // or whatever your preference is here
    // 
  }
}

Таким образом, у вас есть полный контроль над тем, как экземпляр DataContext управляется снаружи и вдали от вашего уровня "Services".Итак, вы могли бы использовать этот DataContextFactory следующим образом:

public interface IRepository
{
  IList<Orders> GetNewOrders();
}
public Repository : IRepository
{
  public IList<Orders> GetNewOrders()
  {
    using (var dataContext = DataContextFactory.GetInstance())
    {
      // dataContext is now your IDataContext to work with
    }
  }
} 

"Как получить доступ к IRepository?" вы можете спросить?

Ваш уровень сервисов будет делать что-то вроде:

public void GetNewOrdersForServices()
{
  // Not recommended!
  //      IRepository repo = new Repository()
  //
  // The following is recommended instead; because, it removes the
  // the Concret reference from your Services layer completely!
  //
  IRepository repo = ServiceLocator.InstanceOf<IRepository>();
  IList myList = repo.GetNewOrders();

}

Или вы могли бы внедрить его в конструктор вашего сервиса, используя ваш любимый вариант инверсии контейнера управления следующим образом:

public class OrderService
{
  private IRepository _repo;

  public OrderService(IRepository repo)
  {
    _repo = repo;
  }

  public void GetNewOrdersForServices()
  {
    IList myList = _repo.GetNewOrders();

  }

Если вы не знакомы с концепциями service locator, ознакомьтесь с Castle Windsor, поскольку он вмещает практически все ваши потребности.

Другие советы

Из того, что я прочитал, используя DataContext "для более чем одного делового разговора это обычно это неправильный поступок." Прокрутите вниз до Почему это так Важно? раздел для цитаты.Из-за кэширования и других факторов вам следует немедленно считать ваш DataContext устаревшим.Исходя из этого, можно с уверенностью сказать, что вы не хотите сохранять DataContext как свойство, которое повторно используется всеми вашими методами.Используя предложение Эрика Дункана, вы захотите передать какую-то фабрику DataContext, чтобы получить новый контекст для каждого запроса.

Для обсуждения, сосредоточенного на DataContext, APress Профессиональный LINQ в книге есть целая глава в DataContext, в самая последняя страница из которых также рекомендуется вам "немедленно считать DataContext устаревшим".

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top