В приведенном ниже упрощенном примере у меня есть DataContext и Repository, которые, как мне кажется, определены довольно разумным образом:
public interface IUnitOfWork
{
int SaveChanges();
}
public class DataContext : DbContext, IUnitOfWork
{
public DbSet<Car> Cars { get ; set; }
}
public interface ICarsRepository
{
Car Find(int id);
void Add(Car car);
}
public class SqlCarsRepository : ICarsRepository
{
private DataContext _context;
public SqlCarsRepository(DataContext context)
{
_context = context;
}
public Car Find(int id)
{
return _context.Cars.Find(id);
}
//etc
}
Я изо всех сил пытаюсь понять, как использовать DI и шаблон абстрактной фабрики для достижения того, чего я хотел бы. В приложении MVC это было бы легко настроить — контроллеру потребуются экземпляры реализаций IUnitOfWork и ICarsRepository в его конструкторе. Я мог бы настроить контейнер так, чтобы он предоставлял мне один и тот же экземпляр DataContext для каждого Http-запроса, используя другую фабрику контроллеров. Почему-то кажется, что здесь одноразовые зависимости расположены правильно.
Однако я хотел бы использовать тот же репозиторий в службе Windows. Это многопоточность, и каждый поток при запуске должен иметь доступ к своему собственному репозиторию, и каждый поток должен иметь свой собственный DataContext/UnitOfWork. Но я не знаю, как это сделать:
- Составной корень приложения — это когда служба запускается, поэтому тогда зависимости не могут быть разрешены для каждого потока (потоки запускаются по требованию).
- Я не уверен, как я могу использовать абстрактный шаблон factory. Потоку нужны экземпляры IUnitOfWork и ICarsRepository, но совместно использующие один и тот же DataContext. Я могу создать абстрактную фабрику, чтобы создать их за один вызов и передать это в поток, но тогда я не знаю, как избавиться от DataContext. Я не хочу, чтобы поток заботился о том, чтобы зависимости от реализации ICarsRepository были одноразовыми. Я определенно не хочу, чтобы поток знал, что ICarsRepository имеет зависимость от DataContext, потому что тогда кажется бессмысленным иметь интерфейс — поток может просто зависеть от SqlCarsRespository.
- Я не хочу делать SqlCarsRepository одноразовым и заставлять его удалять DataContext, потому что могут быть другие, использующие DataContext, и он не создавал его в первую очередь.
- Я думал, что могу создать CarsService, который скрывает IUnitOfWork и ICarsRepository (и получать экземпляры этого с помощью абстрактной фабрики), но я до сих пор не знаю, как избавиться от зависимости DataContext
Каков наилучший способ сделать то, что я пытаюсь?