私は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
により、登録されたインスタンスを 1 つのタスクのコンテキスト内 (およびその 1 つのジョブ オブジェクト内) で共有できるが、外部では共有できないと考えました。
私が抱えている問題は、破棄されたオブジェクトがジョブに挿入されることがありますが、これは明らかにあまり良くありません。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();
});