在下面的简化示例中,我有一个我认为以相当合理的方式定义的 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 的实例。我可以将容器配置为使用不同的控制器工厂为每个 Http 请求提供相同的 DataContext 实例。不知何故,似乎一次性依赖项已正确处理。
但是我想在 Windows 服务中使用相同的存储库。这是多线程的,每个线程在启动时都需要访问自己的存储库,并且每个线程都应该有自己的 DataContext / UnitOfWork。但我不知道该怎么做:
- 应用程序的复合根是服务启动时,因此无法为每个线程解析依赖关系(线程按需启动)。
- 我不确定如何使用抽象工厂模式。线程需要 IUnitOfWork 和 ICarsRepository 的实例,但共享相同的 DataContext。我可以创建一个抽象工厂来在一次调用中创建它们,并将其传递给线程,但是我不知道如何处理 DataContext。我不希望线程必须关心对 ICarsRepository 实现的依赖项是一次性的。我绝对不希望线程知道 ICarsRepository 依赖于 DataContext,因为那样拥有接口似乎毫无意义——线程可能只依赖于 SqlCarsRespository。
- 我不想让 SqlCarsRepository 成为一次性的并让它处理 DataContext,因为可能有其他人在使用 DataContext,而且它一开始并没有创建它。
- 我认为我可以创建一个隐藏 IUnitOfWork 和 ICarsRepository 的 CarsService(并使用抽象工厂获取它的实例),但我仍然不知道如何处理 DataContext 依赖项
做我正在尝试的最好方法是什么?