title: Using Ninject to inject IJob from external assembly into Quartz.net scheduler
body: <p>I'm trying to create an application that can load external assemblies using Ninject and run them on a schedule using Quartz.net.</p>
  
  <p>I have successfully implemented Quartz.net to be injected itself and run jobs based off classes implemented with IJob, from within the same assembly. This works well.</p>
  
  <p>I would like to take it one step further and create a plugin architecture.</p>
  
  <p>I have created a generic interface that all plugins will use, IPlugin, this interface also implements IJob. This is complied and referenced in the main application and each plugin implements it.</p>
  
  <pre><code>using Quartz;
  
  namespace PluginFramework
  {
      public interface IPlugin : IJob
      { }
  }
  </code></pre>
  
  <p><br>
  Then I have a test plugin that implements IPlugin. Very straightforward, it just outputs a timestamp in green.</p>
  
  <pre><code>using System;
  using PluginFramework;
  using Quartz;
  
  namespace TestPlugin
  {
      public class Plugin : IPlugin
      {
          public void Execute(IJobExecutionContext context)
          {
              Start();
          }
  
          private void Start()
          {
              Console.ForegroundColor = ConsoleColor.Green;
              Console.WriteLine(DateTime.Now + " - PLUGIN 1");
          }
      }
  }
  </code></pre>
  
  <p><br></p>
  
  <p>Before I added the Quartz.net framework, I would load and execute the plugin like so. The plugin would load, run once and the application would end, as expected.</p>
  
  <pre><code>var kernel = new StandardKernel();
  
  var assemblies = Directory.GetFiles(@"E:\Plugins\", "*.dll");
  
  foreach (var assembley in assemblies)
  {
      kernel.Load(assembley);
  }
  
  var plugins = kernel.GetAll&lt;IPlugin&gt;();
  
  foreach (var plugin in plugins)
  {
      plugin.Execute();
  }
  </code></pre>
  
  <p><br>
  Now I need the plugin to run on a schedule, but it <em>must</em> still be loaded via Ninject and the main application should remain agnostic to the type, it should just know it's an IJob and be able to run it on a schedule defined in some configuration. This is the bit I am having trouble with.</p>
  
  <p>I have my NinjectJobFactory</p>
  
  <pre><code>public class NinjectJobFactory : IJobFactory
  {
      private IKernel Kernel { get; set; }
  
      public NinjectJobFactory(IKernel kernel)
      {
          Kernel = kernel;
      }
  
      public IJob NewJob(TriggerFiredBundle bundle)
      {
          return (IJob)Kernel.Get(bundle.JobDetail.JobType);
      }
  
      public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
      {
          return (IJob) Kernel.Get(bundle.JobDetail.JobType);
      }
  
      public void ReturnJob(IJob job)
      {
  
      }
  }
  </code></pre>
  
  <p><br>
  My factory provider and scheduler provider.</p>
  
  <pre><code>public class QuartzSchedulerFactoryProvider : Provider&lt;ISchedulerFactory&gt;
  {
      protected override ISchedulerFactory CreateInstance(IContext context)
      {
          var properties = new NameValueCollection();
          var section = (NameValueCollection)ConfigurationManager.GetSection("quartz");
  
          properties["quartz.scheduler.instanceName"] = section["quartz.scheduler.instanceName"];
          properties["quartz.threadPool.type"] = section["quartz.threadPool.type"];
          properties["quartz.threadPool.threadCount"] = section["quartz.threadPool.threadCount"];
          properties["quartz.threadPool.threadPriority"] = section["quartz.threadPool.threadPriority"];
          properties["quartz.jobStore.type"] = section["quartz.jobStore.type"];
          properties["quartz.plugin.xml.type"] = section["quartz.plugin.xml.type"];
          properties["quartz.plugin.xml.fileNames"] = section["quartz.plugin.xml.fileNames"];
  
          return new StdSchedulerFactory(properties);
      }
  }
  </code></pre>
  
  <p><br></p>
  
  <pre><code>public class QuartzSchedulerProvider : Provider&lt;IScheduler&gt;
  {
      private readonly IJobFactory _jobFactory;
      private readonly IEnumerable&lt;ISchedulerListener&gt; _listeners;
      private readonly ISchedulerFactory _schedulerFactory;
  
      public QuartzSchedulerProvider(
          ISchedulerFactory schedulerFactory,
          IJobFactory jobFactory,
          IEnumerable&lt;ISchedulerListener&gt; listeners)
      {
          _jobFactory = jobFactory;
          _listeners = listeners;
          _schedulerFactory = schedulerFactory;
      }
  
      protected override IScheduler CreateInstance(IContext context)
      {
          var scheduler = _schedulerFactory.GetScheduler();
          scheduler.JobFactory = _jobFactory;
  
          foreach (var listener in _listeners)
          {
              scheduler.ListenerManager.AddSchedulerListener(listener);
          }
  
          return scheduler;
      }
  }
  </code></pre>
  
  <p>and some configuration in an external XML file.</p>
  
  <pre><code>&lt;schedule&gt;
      &lt;job&gt;
          &lt;name&gt;Plugin1&lt;/name&gt;
          &lt;group&gt;Plugins&lt;/group&gt;
          &lt;description&gt;&lt;/description&gt;
          &lt;job-type&gt;TestPlugin.Plugin, TestPlugin&lt;/job-type&gt;
          &lt;durable&gt;true&lt;/durable&gt;
          &lt;recover&gt;false&lt;/recover&gt;
      &lt;/job&gt;
  
      &lt;trigger&gt;
          &lt;simple&gt;
              &lt;name&gt;Plugin1&lt;/name&gt;
              &lt;group&gt;Plugins&lt;/group&gt;
              &lt;job-name&gt;Plugin1&lt;/job-name&gt;
              &lt;job-group&gt;Plugins&lt;/job-group&gt;
              &lt;misfire-instruction&gt;SmartPolicy&lt;/misfire-instruction&gt;
              &lt;repeat-count&gt;-1&lt;/repeat-count&gt;
              &lt;repeat-interval&gt;1000&lt;/repeat-interval&gt;
          &lt;/simple&gt;
      &lt;/trigger&gt;
  &lt;/schedule&gt;
  </code></pre>
  
  <p><br>
  Basically I'm not sure how to do it. I've tried a few things based on things I've found on Google/here, but nothing really helped. Any advice would be much appreciated.</p>