EF5的Unity生命周期管理器,具有多线程和存储库模式

时间:2012-06-25 09:45:10

标签: .net entity-framework unity-container .net-4.5

我在SO上看过很多Q / As,说用EF进行mlutithreading很困难。

我得到的场景是Web API将数据库中的作业排队。 Windows服务(实际上是一个控制台应用程序)获取这些作业,在多个线程上运行它们并将结果存储在数据库中。

我目前正在使用存储库模式,并尝试仅使用主线程来更新数据库。这不起作用,因为工作比主线程更新数据库快得多(特别是如果有很多结果(数万))。

接下来的方法是转到每个线程的上下文,我可以通过更改容器上的生命周期管理器来轻松完成,但这会(可能)导致并发问题,其中工作线程将作业状态更新为“完成”但主线程不知道,因为它的缓存副本仍然是“正在进行中”。

我认为下一个方法是按请求进行上下文,但我担心会有很多设置/拆卸 - 特别是有很多线程并行运行。在任何情况下,我都会试一试,看看它有多好/坏。

假设最后一个选项是要走的路,我怎样才能让Unity解析相同的上下文请求?也就是说,如果我这样做......

Dim UnitOfWork = Container.Resolve(Of IUnitOfWork)
Dim UserRepo = Container.Resolve(Of IUserRepository)
Dim RoleRepo = Container.Resolve(Of IRoleRepository)
''Do Stuff
UnitOfWork.Commit

我需要所有对象使用相同的上下文。我是否需要推出自己的终身经理并为每个小组使用一些独特的东西(比如新的Guid)

Dim Key = Guid.NewGuid
Dim UnitOfWork = Container.Resolve(Of IUnitOfWork)(New MyLifetimeManager(Key))
Dim UserRepo = Container.Resolve(Of IUserRepository)(New MyLifetimeManager(Key))

还是有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

不,您只需要单个顶级对象进行解析,这将是其他对象的提供者。例如:

public interface IDalProvider
{
    IUnitOfWork { get; }
    IUserReposiotry { get; }
    ...
}

Unity将解决此接口的实现。如果您将实现实际创建实现或者通过依赖注入传递它们,则由您决定。

在前一种情况下,您将向提供程序实现注入上下文实例,并在构造工作单元和存储库实例时在内部使用它。在后面的例子中,您将直接将上下文实例注入工作单元和存储库实现,并且您将使用Per-resolve生命周期用于上下文,uow和存储库(相同的实例将在单个解析中注入所有依赖对象)。

相关问题