Nhibernate Quartz.NET、NH ISession&;九射镜

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中使用 不确

我正在尝试实现一个基于Quartz.Net运行作业的服务。这些作业可能具有像IRepository这样的依赖项,并且存储库实现将有一个NHibernate ISession注入其中。(Quartz将托管在Windows服务中)。作业通过IJob工厂实现进行解析,IJob工厂实现使用Ninject进行解析(目前封装在IServiceLocator实现中)

工作范围

我希望能够使用Ninject确定每个作业的ISession范围,以便每个作业创建一个会话,可以在多个IRepository中使用

不确定这是否可行,但我想知道是否有人有这方面的经验

我是否可以使用作业上下文创建Kernel.InScope(???)使用的范围

Quartz.Net IJobFactory:

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();你能发布你的解决方案吗?我也有同样的问题。