Nhibernate Quartz.NET、NH ISession&;九射镜
我正在尝试实现一个基于Quartz.Net运行作业的服务。这些作业可能具有像IRepository这样的依赖项,并且存储库实现将有一个NHibernate ISession注入其中。(Quartz将托管在Windows服务中)。作业通过IJob工厂实现进行解析,IJob工厂实现使用Ninject进行解析(目前封装在IServiceLocator实现中) 工作范围 我希望能够使用Ninject确定每个作业的ISession范围,以便每个作业创建一个会话,可以在多个IRepository中使用 不确定这是否可行,但我想知道是否有人有这方面的经验 我是否可以使用作业上下文创建Kernel.InScope(???)使用的范围 Quartz.Net IJobFactory:Nhibernate Quartz.NET、NH ISession&;九射镜,nhibernate,scope,ninject,quartz.net,Nhibernate,Scope,Ninject,Quartz.net,我正在尝试实现一个基于Quartz.Net运行作业的服务。这些作业可能具有像IRepository这样的依赖项,并且存储库实现将有一个NHibernate ISession注入其中。(Quartz将托管在Windows服务中)。作业通过IJob工厂实现进行解析,IJob工厂实现使用Ninject进行解析(目前封装在IServiceLocator实现中) 工作范围 我希望能够使用Ninject确定每个作业的ISession范围,以便每个作业创建一个会话,可以在多个IRepository中使用 不确
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<>));
InitializeIoC();
scheduler = schedulerFactory.GetScheduler();
scheduler.JobFactory = ServiceLocator.Resolve<IJobFactory>();
InitializeJobs();
scheduler.Start();
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
}
//服务定位器
绑定()到();
//石英绑定
绑定()到();
//NHibernate结合
Bind().ToMethod(ctx=>ctx.Kernel.Get().BuildSessionFactory()).InSingletonScope();
Bind().ToMethod(ctx=>ctx.Kernel.Get().OpenSession());//ToDo:了解如何定义会话的范围
//存储库绑定
绑定(typeof(IRepository))到(typeof(ReadWriteRepository));
主执行:
//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<>));
InitializeIoC();
scheduler = schedulerFactory.GetScheduler();
scheduler.JobFactory = ServiceLocator.Resolve<IJobFactory>();
InitializeJobs();
scheduler.Start();
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
}
InitializeIoC();
scheduler=schedulerFactory.GetScheduler();
scheduler.JobFactory=ServiceLocator.Resolve();
初始化jobs();
scheduler.Start();
作业示例:
//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<>));
InitializeIoC();
scheduler = schedulerFactory.GetScheduler();
scheduler.JobFactory = ServiceLocator.Resolve<IJobFactory>();
InitializeJobs();
scheduler.Start();
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
}
公共类TestJob3:IJob
{
私人只读易读回购;
私人只读的IRepository orderRepo;
公开测试工作3(易趣回购、易趣订单回购)
{
//orderRepo和repo应具有相同的会话
this.repo=回购;
this.oderRepo=orderepo;
System.Diagnostics.Debug.WriteLine(“创建了作业3”);
}
#IJob的区域实施
public void Execute(IJobExecutionContext上下文)
{
System.Diagnostics.Debug.WriteLine(“作业3正在执行”);
使用(var scope=new TransactionScope())
{
var customer=repo.GetById(1);
customer.Name=“蓝山羊”;
回购保存(客户);
scope.Complete();
}
}
#端区
}
**存储库代码段:**
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;
}
}
public类ReadWriteRepository:IRepository其中tenty:class,IRootEntity
{
专用只读会话;
公共读写存储(ISession会话)
{
this.session=会话;
}
公共虚拟地址GetById(int id)
{
var entity=session.Get(id);
返回实体;
}
公共虚拟TEntity保存(TEntity实体)
{
会话。保存或更新(实体);
返回实体;
}
}
谢谢你抽出时间
更新
我最终使用了Remo的建议,并使用了InCallScope():
Bind().ToMethod(ctx=>ctx.Kernel.Get().OpenSession()).InCallScope();
我喜欢这样想(正确与否?)是从“初始”get开始的所有内容在整个依赖关系树中重用相同的项
我目前正在使用一个激活块,它似乎正在工作,但我将尝试使用InCallScope扩展。谢谢Remo,你能用激活块发布你的解决方案吗?@MuriloLima我没有使用激活块的解决方案。“我不会用那个。”穆里洛利马-最后我接受了雷莫的建议,使用了InCallScope,它工作得很好。Bind().ToMethod(ctx=>ctx.Kernel.Get().OpenSession()).InCallScope();你能发布你的解决方案吗?我也有同样的问题。