我EntityFramework
在一堆后台作业类中使用和实现通用存储库和工作单元模式。作业类是使用 Unity DI 创建的,因此它们可以注入依赖项,这些依赖项主要是存储库和UnitOfWork
对象。存储库和工作单元应该共享 EF DbContext
。
一个常见的工作如下所示:
public class CommonJob : IJob, IDisposable
{
private IRepo<SomeEntity> _repo;
private IUnitOfWork _uow;
public CommonJob(IRepo<SomeEntity> repo, IUnitOfWork uow)
{
_repo = repo;
_uow = uow;
}
public void RunJob()
{
// do stuff here
}
public void Dispose()
{
_uow.Commit();
_uow.Dispose();
}
}
所有作业都在新任务中运行,就像这样
Task.Factory.StartNew(() => {
// container is UnityContainer
var job = container.Resolve<CommonJob>();
job.RunJob();
job.Dispose();
});
而且我已经使用 Unity 向 Unity 注册了工作单元和存储库PerThreadLifetimeManager
,认为这将允许在一项任务的上下文中(以及在该任务对象中)共享注册的实例,但不能在外部共享。
我遇到的问题是,有时作业会被注入已处理的对象,这显然不是很好。我一直在阅读Task.Factory.StartNew()
并不总是使用新线程。这是否意味着PerThreadLifetimeManager
将在任务之间共享对象?如果这是真的,是否有另一种统一管理对象提升时间的方法,这将允许每个任务独立工作,而不管它运行在哪个线程上?
编辑:
虽然下面选择的答案将实现相同的效果,但我最终使用HierarchicalLifetimeManager
和子容器来实现每个作业的依赖隔离。
这是一个例子:
// registering the dependencies,
// these should be singletons, but only within the context of one job
_container.Register(typeof(IRepo<>), typeof(Repo<>), new HierarchicalLifetimeManager())
.Register<IUnitOfWork, UnitOfWork>(new HierarchicalLifetimeManager());
// starting a new job
Task.Factory.StartNew<IUnityContainer>(() =>
{
// create a child container to remove instance sharing between tasks
var childContainer = _container.CreateChildContainer();
// figure out and resolve the job class from the child container
// this will make sure that different jobs do not share instances
var jobType = GetJobType();
var job = childContainer.Resolve(jobType) as IJob;
job.RunJob();
return childContainer;
}).ContinueWith(previousTask => {
// when the job is done, dispose of the child container
task.Result.Dispose();
});