Asp.net mvc ASP.NET nHibernate+;Quartz.NET+;统一

Asp.net mvc ASP.NET nHibernate+;Quartz.NET+;统一,asp.net-mvc,nhibernate,fluent-nhibernate,unity-container,quartz.net,Asp.net Mvc,Nhibernate,Fluent Nhibernate,Unity Container,Quartz.net,我正在开发一个ASP.NETMVC的web应用程序。基于nHibernate使用与数据存储库交互。存储库是通过Unity实例化的。对每个请求的存储库解析ISession 现在我需要添加到在后台执行定期计划任务的项目爬虫中。要实现爬虫程序,请选择Quartz.NET。一个项目可以有多个不同的Walker,通过存储库与数据库交互时,如果它们的任务执行情况相匹配 问题是爬虫程序必须创建另一个会话,因为它基于一个请求解决方案不工作(没有web请求)。它是在一个解决方案中实现的,在该解决方案中,我注册了I

我正在开发一个ASP.NETMVC的web应用程序。基于nHibernate使用与数据存储库交互。存储库是通过Unity实例化的。对每个请求的存储库解析ISession

现在我需要添加到在后台执行定期计划任务的项目爬虫中。要实现爬虫程序,请选择Quartz.NET。一个项目可以有多个不同的Walker,通过存储库与数据库交互时,如果它们的任务执行情况相匹配

问题是爬虫程序必须创建另一个会话,因为它基于一个请求解决方案不工作(没有web请求)。它是在一个解决方案中实现的,在该解决方案中,我注册了ISession的两个不同实现,但它不起作用。下面是代码示例

出现以下问题:

  • 这是解决问题的正确方向吗
  • 如何正确实施
  • 这种方法会不会使两个爬虫试图写入数据库,从而导致错误
  • 代码:

    公共类数据库存储注册:IUnityRegistration
    {
    公共无效寄存器(IUnityContainer容器)
    {
    //网
    var connectionString=WebConfiguration Manager.connectionString[“DefaultConnection”]。connectionString;
    SessionManager.ConnectionString=ConnectionString;
    container.RegisterType(新的层次结构CallifetimeManager(),
    新注入工厂(c=>SessionManager.CurrentSession)
    );
    RegisterType(新的层次结构CallifetimeManager());
    RegisterType(typeof(IRepository)、typeof(NHibernateRepository)、新层次结构CallifeTimeManager());
    //外部
    container.RegisterType(“ext”,新层次结构CallifetimeManager(),新注入工厂(c=>
    {
    var config=fluntly.Configure()。
    数据库(
    MSSQL配置
    .MsSql2008
    .ConnectionString(ConnectionString)
    .UseReflectionOptimizer()
    )
    .Mappings(m=>m.FluentMappings.AddFromAssemblyOf())
    .BuildConfiguration();
    var sessionFactory=config.BuildSessionFactory();
    返回sessionFactory.OpenSession();
    }));
    container.RegisterType(typeof(IRepository)、typeof(NHibernateRepository)、“ext”、新层次结构callifetimemanager()、新注入构造函数(新解析参数(“ext”);
    }
    }
    

    公共类调度任务:MvcStartupTaskBase
    {
    专用只读IUnityContainer容器;
    公共调度任务(IUnityContainer容器)
    {
    this.container=容器;
    }
    公共覆盖无效运行()
    {
    var scheduler=container.Resolve();
    scheduler.JobFactory=新UnityJobFactory(容器);
    scheduler.Start();
    var job=JobBuilder.Create().Build();
    var trigger=TriggerBuilder.Create()
    .使用DailyTimeIntervals时间表
    (s=>
    s、 间隔分钟(1)
    .每天一次
    .StartingDailyAt(一天的时间、小时和分钟(0,0))
    )
    .Build();
    ScheduleJob(作业,触发器);
    }
    公共类UnityJobFactory:IJobFactory
    {
    专用只读IUnityContainer容器;
    公共单元作业工厂(IUnityContainer容器)
    {
    this.container=容器;
    }
    公共IJob NewJob(TriggerFiredBundle包,IScheduler调度器)
    {
    return(IJob)container.Resolve(bundle.JobDetail.JobType,“ext”);
    }
    公共作业(IJob作业)
    {
    }
    }
    }
    

    公共类上载转换任务:IJob
    {
    公共上载转换任务(IRepository UploadRepository){
    //存储库的会话已关闭!
    }
    public void Execute(IJobExecutionContext上下文)
    {
    }
    }
    
    您的计划程序设置为run方法中的局部变量。它必须是一个存在时间足够长的变量,以便调度器运行任务。在不知道整个项目的细节的情况下,应该将调度程序设置为在应用程序启动时创建的单例。然后,在调度作业时引用此单例实例

    理想情况下,您的计划程序应该作为一个单独的长期运行的服务运行,例如windows服务

    public class DatabaseRepositoriesRegistration : IUnityRegistration
    {
        public void Register(IUnityContainer container)
        {
            // web
            var connectionString = WebConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
            SessionManager.ConnectionString = connectionString;
            container.RegisterType<ISession>(new HierarchicalLifetimeManager(),
                new InjectionFactory(c => SessionManager.CurrentSession)
               );
    
            container.RegisterType<IUnitOfWork, NHibernateUnitOfWork>(new HierarchicalLifetimeManager());
            container.RegisterType(typeof(IRepository<>), typeof(NHibernateRepository<>), new HierarchicalLifetimeManager());
    
            // externals
    
            container.RegisterType<ISession>("ext", new HierarchicalLifetimeManager(), new InjectionFactory(c =>
            {
                var config = Fluently.Configure().
                Database(
                    MsSqlConfiguration
                        .MsSql2008
                        .ConnectionString(connectionString)
                        .UseReflectionOptimizer()
                        )
                .Mappings(m => m.FluentMappings.AddFromAssemblyOf<MappingBeacon>())
                .BuildConfiguration();
    
                var sessionFactory = config.BuildSessionFactory();
                return sessionFactory.OpenSession();
            }));
    
            container.RegisterType(typeof(IRepository<>), typeof(NHibernateRepository<>), "ext", new HierarchicalLifetimeManager(), new InjectionConstructor(new ResolvedParameter<ISession>("ext")));
        }
    }
    
    public class SchedulerTask : MvcStartupTaskBase
    {
        private readonly IUnityContainer container;
    
        public SchedulerTask(IUnityContainer container)
        {
            this.container = container;
        }
    
        public override void Run()
        {
            var scheduler = container.Resolve<IScheduler>();
            scheduler.JobFactory = new UnityJobFactory(container);
            scheduler.Start();
    
            var job = JobBuilder.Create<UploadConvertionTask>().Build();
    
            var trigger = TriggerBuilder.Create()
                .WithDailyTimeIntervalSchedule
                  (s =>
                     s.WithIntervalInMinutes(1)
                    .OnEveryDay()
                    .StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(0, 0))
                  )
                .Build();
    
            scheduler.ScheduleJob(job, trigger);
        }
    
        public class UnityJobFactory : IJobFactory
        {
            private readonly IUnityContainer container;
    
            public UnityJobFactory(IUnityContainer container)
            {
                this.container = container;
            }
    
            public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
            {
                return (IJob)container.Resolve(bundle.JobDetail.JobType, "ext");
            }
    
            public void ReturnJob(IJob job)
            {
            }
        }
    }
    
    public class UploadConvertionTask: IJob
    {
        public UploadConvertionTask(IRepository<Upload> uploadRepositiory) {
            // for repository session is closed!
        }
    
        public void Execute(IJobExecutionContext context)
        {
    
        }
    }