2012-03-07 54 views
5

我試圖實現一個基於Quartz.Net的作業。作業可能具有像IRepository <>的依賴關係,並且存儲庫實現將注入一個NHibernate ISession。 (Quartz將託管在Windows服務中)。通過使用Ninject解析的IJob工廠實現解決作業(當前包裝在IServiceLocator實現中)。Quartz.NET,NH ISession&Ninject Scope

工作範圍

我想能夠使用Ninject到每範圍的作業ISession的,以便有每個作業創建一個會話可以在多個IRepository <>的使用。

不知道這是否可能,但我想知道是否有人有這方面的經驗?

我可以以某種方式使用Job上下文來創建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綁定:

 //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<>)); 

主執行:

​​

示例工作:

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 
} 

**庫段:**

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; 
    } 
} 

感謝您抽出寶貴的時間!

更新 我結束了使用雷莫的建議,並正在使用InCallScope():

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

我喜歡把它(?正確與否)是「初始」一切礙事整個依賴關係樹重複使用相同的項目

+1

你能發佈你的解決方案嗎?我遇到了同樣的問題。 – 2012-12-17 18:59:13

回答

2
+0

我目前正在使用一個似乎正在工作的激活塊,但我會試一試InCallScope擴展。謝謝! – 2012-03-09 00:09:56

+0

雷莫,你可以使用激活塊發佈你的解決方案嗎? – 2012-12-17 18:53:30

+0

@MuriloLima我沒有解決這個使用激活塊。我不會使用它。 – 2012-12-18 00:23:08