В 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 - поддерживая разделение концерта в силе, маскируя основные требования:
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 (или другой класс) (возможно, вы хотите хранить статическую ссылку или изменять настройки на основе WebRequest и т. Д.), Вам нужно будет использовать «Factory».
Фабрика будет выглядеть примерно так:
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();
}
Или вы бы добавили его в конструктор вашего сервиса, используя ваш любимый вариант контейнера Inversion of Control, например:
public class OrderService
{
private IRepository _repo;
public OrderService(IRepository repo)
{
_repo = repo;
}
public void GetNewOrdersForServices()
{
IList myList = _repo.GetNewOrders();
}
Если вы не сходитесь с концепциями поиска сервисов, ознакомьтесь с Castle Windsor, так как он охватывает практически все ваши потребности.