在下面的简化示例中,我有一个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应用程序中,这很容易设置-- Controller需要在其构造函数中实现IUnitOfWork和ICarsRepository的实例。我可以配置容器,使用不同的控制器工厂,为每个Http请求提供相同的DataContext实例。在这里,似乎正确地处理了一次性依赖项。
但是,我希望在windows服务中使用相同的存储库。这是多线程的,每个线程启动时都需要访问自己的存储库,每个线程都应该有自己的DataContext / UnitOfWork。但我不知道该怎么做
做我想做的事最好的方法是什么?
发布于 2012-06-28 11:24:23
因此,不能为每个线程解析依赖关系。
他们可以,事实上,他们应该。您应该在每个线程的开头解析一个新的对象图。不这样做,意味着您只能使用线程安全的依赖项,这在您的情况下不是这样的。
我不知道如何使用抽象的工厂模式
我认为,首先,尝试将DataContext定义为MVC应用程序中的Web请求和windows服务中的生存期范围(或您使用的容器中的任何可用内容)。在windows服务中,每个线程都将获得自己的生存期范围。定义作用域通常允许在作用域结束时释放实例。
我不希望线程关心对ICarsRepository实现的依赖--它是一次性的
您的线程应该关心这个问题,但是您的业务逻辑不应该关心这个问题。在启动新线程时,您必须有一些基础结构代码,允许启动和结束一个范围,以及解析和使用图形的根类型。这段代码应该是组合根的一部分,所以应用程序的其他部分应该忽略这一点。如果您用每个生命周期范围(或其他一些显式生存期)注册了某些类型,则容器将知道何时释放这些实例。基础结构代码只需告诉容器范围已经结束。
我不想让SqlCarsRepository变成一次性的
SqlCarsRepository应该依赖于一个不实现IDisposable的接口,在这种情况下没有什么可处理的。它应该是负责处理DataContext的容器,通过适当的注册,您可以这样做。
做我想做的事最好的方法是什么?
您的设计听起来是合理的,但是这里还有一些其他的问题,这可能会给您提供更多的工作:
https://stackoverflow.com/questions/11242166
复制相似问题