Note that there are some explanatory texts on larger screens.

plurals
  1. POQuartz.NET, NH ISession & Ninject Scope
    primarykey
    data
    text
    <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>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload