I need to call something in my application start to start my quartz.net scheduler.
The problem is that I need to pass in a repository into my service layer that normally is done with ninject and dependency injection.
//global.aspx
public class MvcApplication : System.Web.HttpApplication
{
private readonly IScheduledRemindersService scheduledRemindersService;
public MvcApplication(IScheduledRemindersService
scheduledRemindersService)
{
this.scheduledRemindersService = scheduledRemindersService;
}
protected void Application_Start()
{
//other default stuff here like mvc routers.
scheduledRemindersService.RemindersSchedule();
}
}
private readonly IReminderRepo reminderRepo;
public ScheduledRemindersService(IReminderRepo reminderRepo)
{
this.reminderRepo = reminderRepo;
}
private readonly IReminderRepo reminderRepo;
public ScheduledRemindersService(IReminderRepo reminderRepo)
{
this.reminderRepo = reminderRepo;
}
I have NHibernate set to so when It seems IReminderRepo it shoudl bind it and in IReminderRepo I have
private readonly ISession session;
public ReminderRepo(ISession session)
{
this.session = session;
}
This will also get automatically binded through nhibernate.
This won’t work though as the global.aspx only allows no argument constructors.
So how can inject the right classes to these interfaces? Especially the nhibernate session that is the most important thing I need.
Edit
public class NhibernateSessionFactoryProvider : Provider<ISessionFactory>
{
protected override ISessionFactory CreateInstance(IContext context)
{
var sessionFactory = new NhibernateSessionFactory();
return sessionFactory.GetSessionFactory();
}
}
public class NhibernateModule : NinjectModule
{
public override void Load()
{
Bind<ISessionFactory>().ToProvider<NhibernateSessionFactoryProvider>().InSingletonScope();
Bind<ISession>().ToMethod(context => context.Kernel.Get<ISessionFactory>().OpenSession()).InRequestScope();
}
}
// in the global.aspx
protected IKernel CreateKernel()
{
var modules = new INinjectModule[]
{
new NhibernateModule(),
new ServiceModule(),
new RepoModule(),
};
return new StandardKernel(modules);
}
// in RepoModule()
Bind<IReminderRepo>().To<ReminderRepo>();
// in serviceModule
Bind<IScheduledRemindersService>().To<ScheduledRemindersService>()
We use a method like this in our Global.asax.cs file for exactly this purpose (it gets called from Application_Start:
And we have
IJobFactorybound to the following class:And IObjectFactory is a simple interface that just abstracts away the Kernel so we’re not depending on Ninject everywhere:
IObjectFactoryis then bound to a class like this:… using a binding that looks like this:
So the overall effect is that we use the Ninject kernel to create the IJobFactory, which uses constructor injection to take an
IObjectFactory<IJob>, which is invoked to produce anyIJobs that Quartz requires. Those job classes can therefore use constructor-based injection, and Ninject is indirectly instantiating them.