Tôi đang sử dụng EntityFramework
và triển khai một kho lưu trữ chung và mẫu đơn vị công việc trong một loạt các lớp công việc nền. Các lớp công việc được tạo ra bằng cách sử dụng Unity DI để chúng có thể được tiêm với các phụ thuộc, mà chủ yếu là các kho và đối tượng UnitOfWork
. Kho lưu trữ và đơn vị công việc phải chia sẻ EF DbContext
.Unity PerThreadLifetimeManager and Tasks
Một công việc chung sẽ trông như thế này:
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();
}
}
Tất cả các công việc đang chạy trong nhiệm vụ mới, một cái gì đó như thế này
Task.Factory.StartNew(() => {
// container is UnityContainer
var job = container.Resolve<CommonJob>();
job.RunJob();
job.Dispose();
});
Và tôi đã đăng ký đơn vị-of-nơi làm việc và kho với Unity sử dụng PerThreadLifetimeManager
, nghĩ rằng điều đó sẽ cho phép chia sẻ các cá thể đã đăng ký trong ngữ cảnh của một nhiệm vụ (và trong một đối tượng công việc đó), nhưng không phải ở bên ngoài.
Sự cố mà tôi gặp phải là đôi khi công việc sẽ được tiêm các đối tượng được xử lý, điều này rõ ràng là không tốt lắm. Tôi đã đọc rằng Task.Factory.StartNew()
không phải lúc nào cũng sử dụng một chủ đề mới. Điều này có nghĩa là PerThreadLifetimeManager
sẽ chia sẻ các đối tượng giữa các tác vụ? Nếu điều này là đúng, có cách nào khác để quản lý thời gian chờ của đối tượng với sự thống nhất, điều này sẽ cho phép mỗi tác vụ làm việc trong sự cô lập, bất kể chuỗi nó đang chạy chưa?
EDIT:
Trong khi câu trả lời được lựa chọn dưới đây sẽ đạt được điều tương tự, tôi đã kết thúc bằng cách sử dụng HierarchicalLifetimeManager
và con container để đạt được cách ly phụ thuộc cho từng công việc.
Dưới đây là một ví dụ:
// 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();
});
Câu trả lời của bạn là chính xác, nhưng tôi chỉ muốn thêm rằng tôi đã kết thúc bằng cách sử dụng một 'HieararchicalLiftetimeManager' và tạo một thùng chứa con trong nhiệm vụ. Điều này là do tôi cần sử dụng vùng chứa để giải quyết động một số dịch vụ từ một trong các lớp công việc. Tôi biết sử dụng một container như một định vị dịch vụ là một mùi mã, nhưng đó là cách nó được thiết lập, và không có thời gian để sửa nó ... – Pinetree
@Pinetree Bất kỳ cơ hội nào bạn có thể chỉ ra cách bạn đã làm điều này? Cảm ơn – nfplee
@nfplee Tôi không có mã ở nhà và tôi không nhớ nó ở trên đầu của tôi. Tôi sẽ đăng những gì tôi đã làm vào thứ hai khi tôi đi làm. – Pinetree