3

在下面的简化示例中,我有一个我认为以相当合理的方式定义的 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 依赖项

做我正在尝试的最好方法是什么?

4

1 回答 1

2

因此无法为每个线程解决依赖关系

他们可以,而且事实上,他们应该这样做。您应该在每个线程的开头解析一个新的对象图。不这样做意味着您只能使用线程安全的依赖项,而您的情况并非如此。

我不确定如何使用抽象工厂模式

我认为首先,尝试DataContext在您的 MVC 应用程序中将您定义为 Per Web Request,并在您的 Windows 服务中定义为 Per Lifetime Scope(或您使用的容器中可用的任何内容)。在您的 Windows 服务中,每个线程都将获得自己的生命周期范围。定义范围通常允许您在范围结束时释放实例。

我不希望线程必须关心对 ICarsRepository 实现的依赖项是一次性的

您的线程应该关心这一点,但您的业务逻辑不应该。启动新线程时,您将必须拥有一些允许启动和结束范围以及解析和使用图的根类型的基础架构代码。此代码应该是您的组合根的一部分,因此应用程序的其余部分应该忽略这一点。如果您使用 Per Lifetime Scope(或其他显式生命周期)注册了某些类型,您的容器将知道何时处置这些实例。基础设施代码只需要告诉容器,范围已经结束。

我不想让 SqlCarsRepository 一次性

SqlCarsRepository应该依赖于一个没有实现的接口,在IDisposable这种情况下没有什么可以处理的。它应该是负责处理 的容器DataContext,并且通过正确的注册,您可以执行此操作。

做我正在尝试的最好方法是什么?

你的设计听起来很合理,但这里有一些其他的 SO 问题,可能会给你更多的工作:

于 2012-06-28T11:24:23.100 回答