title: Quartz.NET, NH ISession & Ninject Scope
body: <p>I'm trying to implement a service that will run jobs based on Quartz.Net.  The jobs may have dependencies like IRepository&lt;> and the repository implementation will have a NHibernate ISession injected into it.  (Quartz will be hosted in a Windows Service).  Jobs are resolved via a IJob factory implementation that uses Ninject to resolve (currently wrapped in a IServiceLocator implementation).</p>
  
  <p><strong>Job Scope</strong></p>
  
  <p>I would like to be able to use Ninject to scope the ISession per Job so that there is one session created per job that may be used in multiple IRepository&lt;>'s .</p>
  
  <p>Not sure if this is possible but am wondering if anyone has experience with this?</p>
  
  <p>Can I somehow use the Job context to create a Scope that is used by Kernel.InScope(???).</p>
  
  <p><strong>Quartz.Net IJobFactory:</strong>  </p>
  
  <pre><code>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;
          }
      }
  }
  </code></pre>
  
  <p><strong>Ninject Bindings:</strong></p>
  
  <pre><code>        //Service Locator
          Bind&lt;IServiceLocator&gt;().To&lt;NinjectAdapter&gt;();
  
          //Quartz Bindings
          Bind&lt;IJobFactory&gt;().To&lt;JobFactory&gt;();
  
          //NHibernate Bindings
          Bind&lt;ISessionFactory&gt;().ToMethod(ctx =&gt; ctx.Kernel.Get&lt;NHibernateConfiguration&gt;().BuildSessionFactory()).InSingletonScope();
          Bind&lt;ISession&gt;().ToMethod(ctx =&gt; ctx.Kernel.Get&lt;ISessionFactory&gt;().OpenSession());// ToDo: Figure out how to scope session
  
          //Repository Bindings
          Bind(typeof (IRepository&lt;&gt;)).To(typeof (ReadWriteRepository&lt;&gt;));
  </code></pre>
  
  <p><strong>Main Execution:</strong></p>
  
  <pre><code>        InitializeIoC();
          scheduler = schedulerFactory.GetScheduler();
          scheduler.JobFactory = ServiceLocator.Resolve&lt;IJobFactory&gt;();
          InitializeJobs();
          scheduler.Start();
  </code></pre>
  
  <p><strong>Example Job:</strong></p>
  
  <pre><code>public class TestJob3 : IJob
  {
      private readonly IRepository&lt;Customer&gt; repo;
      private readonly IRepository&lt;Order&gt; orderRepo;
  
      public TestJob3(IRepository&lt;Customer&gt; repo, IRepository&lt;Order&gt; 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
  }
  </code></pre>
  
  <p>** Repository Snippet: **</p>
  
  <pre><code>public class ReadWriteRepository&lt;TEntity&gt; : IRepository&lt;TEntity&gt; 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&lt;TEntity&gt;(id);
          return entity;
      }
  
      public virtual TEntity Save(TEntity entity)
      {
          session.SaveOrUpdate(entity);
          return entity;
      }
  }
  </code></pre>
  
  <p>Thanks for taking the time!</p>
  
  <p><strong>Update</strong>
  I ended up using Remo's suggestion and am using InCallScope():</p>
  
  <pre><code>Bind&lt;ISession&gt;().ToMethod(ctx =&gt; ctx.Kernel.Get&lt;ISessionFactory&gt;().OpenSession()).InCallScope();
  </code></pre>
  
  <p>The way I like to think of it (correct or not?) is everything from the "initial" get reuses the same items throughout the dependency tree</p>