我正在使用EntityFramework
並在一堆後臺作業類中實現通用存儲庫和工作單元模式。作業類是使用Unity DI創建的,因此它們可以注入依賴項,這些依賴項主要是存儲庫和UnitOfWork
對象。 知識庫和工作單元應共享EF DbContext
。Unity PerThreadLifetimeManager和任務
一個共同的工作應該是這樣的:
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使用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();
});
你的回答是正確的,但我只是想補充說,我最終使用了'HieararchicalLiftetimeManager'並在任務中創建了一個子容器。這是因爲我需要使用容器來動態解析其中一個作業類的一些服務。我知道使用容器作爲服務定位器是一種代碼味道,但這就是它的設置,現在沒有時間去修復它... – Pinetree
@Pinetree任何機會,你可以展示你如何做到這一點?謝謝 – nfplee
@nfplee我在家裏沒有代碼,我不記得它在我的頭頂。我將在星期一上班時發佈我所做的事情。 – Pinetree