Можно ли установить Datacontext в качестве свойства в репозитории?
-
03-07-2019 - |
Вопрос
Есть ли какая-либо потенциальная проблема в установке 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 устаревшим".