2012-03-07 23 views
5

Tôi đang cố gắng triển khai một dịch vụ sẽ chạy công việc dựa trên Quartz.Net. Các công việc có thể có các phụ thuộc như IRepository <> và việc triển khai kho lưu trữ sẽ có một ISession NHibernate được chèn vào nó. (Quartz sẽ được lưu trữ trong một dịch vụ Windows). Công việc được giải quyết thông qua việc triển khai nhà máy IJob sử dụng Ninject để giải quyết (hiện được bao bọc trong một triển khai IServiceLocator).Quartz.NET, NH ISession & Ninject Scope

Phạm vi công việc

Tôi muốn để có thể sử dụng Ninject phạm vi các ISession mỗi công việc để có một phiên tạo cho mỗi công việc mà có thể được sử dụng trong nhiều IRepository <> 's.

Không chắc chắn nếu điều này là có thể nhưng tôi tự hỏi nếu có ai có kinh nghiệm với điều này?

Bằng cách nào đó tôi có thể sử dụng ngữ cảnh Công việc để tạo một Phạm vi được sử dụng bởi Kernel.InScope (???).

Quartz.Net IJobFactory:

public class JobFactory : IJobFactory 
{ 
    readonly IServiceLocator locator; 

    public JobFactory(IServiceLocator locator) 
    { 
     this.locator = locator; 
    } 

    public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler) 
    { 
     try 
     {    
      var jobDetail = bundle.JobDetail; 
      var jobType = jobDetail.JobType; 

      return (IJob)locator.Resolve(jobType); 
     } 
     catch (Exception e) 
     { 
      var se = new SchedulerException("Problem instantiating class", e); 
      throw se; 
     } 
    } 
} 

Ninject Bindings:

 //Service Locator 
     Bind<IServiceLocator>().To<NinjectAdapter>(); 

     //Quartz Bindings 
     Bind<IJobFactory>().To<JobFactory>(); 

     //NHibernate Bindings 
     Bind<ISessionFactory>().ToMethod(ctx => ctx.Kernel.Get<NHibernateConfiguration>().BuildSessionFactory()).InSingletonScope(); 
     Bind<ISession>().ToMethod(ctx => ctx.Kernel.Get<ISessionFactory>().OpenSession());// ToDo: Figure out how to scope session 

     //Repository Bindings 
     Bind(typeof (IRepository<>)).To(typeof (ReadWriteRepository<>)); 

Thực hiện chính:

 InitializeIoC(); 
     scheduler = schedulerFactory.GetScheduler(); 
     scheduler.JobFactory = ServiceLocator.Resolve<IJobFactory>(); 
     InitializeJobs(); 
     scheduler.Start(); 

Ví dụ công việc:

public class TestJob3 : IJob 
{ 
    private readonly IRepository<Customer> repo; 
    private readonly IRepository<Order> orderRepo; 

    public TestJob3(IRepository<Customer> repo, IRepository<Order> orderRepo) 
    { 
     //orderRepo and repo should have the same ISession 

     this.repo = repo; 
     this.oderRepo = orderRepo; 
     System.Diagnostics.Debug.WriteLine("Job 3 Created"); 
    } 

    #region Implementation of IJob 

    public void Execute(IJobExecutionContext context) 
    { 
     System.Diagnostics.Debug.WriteLine("Job 3 Executing"); 
     using (var scope = new TransactionScope()) 
     { 
      var customer = repo.GetById(1); 
      customer.Name = "Blue Goats"; 
      repo.Save(customer); 
      scope.Complete(); 
     } 
    } 

    #endregion 
} 

** Repository Snippet: **

public class ReadWriteRepository<TEntity> : IRepository<TEntity> where TEntity : class, IRootEntity 
{ 
    private readonly ISession session; 

    public ReadWriteRepository(ISession session) 
    { 
     this.session = session; 
    } 

    public virtual TEntity GetById(int id) 
    { 
     var entity = session.Get<TEntity>(id); 
     return entity; 
    } 

    public virtual TEntity Save(TEntity entity) 
    { 
     session.SaveOrUpdate(entity); 
     return entity; 
    } 
} 

Cảm ơn đã dành thời gian!

Cập nhật tôi đã kết thúc bằng đề nghị Remo và đang sử dụng InCallScope():

Bind<ISession>().ToMethod(ctx => ctx.Kernel.Get<ISessionFactory>().OpenSession()).InCallScope(); 

Con đường tôi thích nghĩ về nó (? Đúng hay không) là tất cả mọi thứ từ "ban đầu" nhận tái sử dụng các mặt hàng tương tự trong suốt cây phụ thuộc

+1

Bạn có thể đăng giải pháp của mình không? Tôi có cùng một vấn đề. –

Trả lời

2
+0

Tôi hiện đang sử dụng một khối kích hoạt có vẻ như đang hoạt động nhưng tôi sẽ thử phần mở rộng InCallScope. Cảm ơn! –

+0

Làm lại, bạn có thể đăng giải pháp của mình bằng cách sử dụng Khối kích hoạt không? –

+0

@MuriloLima Tôi không có giải pháp cho việc này bằng cách sử dụng Khối kích hoạt. Tôi sẽ không sử dụng nó. –