我正在为ASP.NET MVC开发一个Web应用程序。基于nHibernate使用与数据存储库交互。存储库通过Unity实例化。根据请求存储已解析的ISession。
现在我需要添加项目抓取工具在后台执行定期计划任务。实现一个爬虫选择Quartz.NET。项目可以有几个不同的步行者,同时通过存储库与数据库交互,如果匹配任务的执行。
问题是爬虫必须创建另一个会话,因为它基于请求解决方案不起作用(没有Web请求)。它实现了一个解决方案,我在其中注册了两个不同的ISession实现,但它不起作用。代码示例如下。
出现以下问题:
代码:
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)
{
}
}
答案 0 :(得分:1)
您的调度程序在run方法中设置为局部变量。它需要是一个足以让调度程序运行任务的变量。在不知道整个项目的细节的情况下,您应该将调度程序设置为在应用程序启动时创建的单例。然后,在您安排作业时引用此单例实例。
理想情况下,您的调度程序应作为单独的长期运行服务运行,例如Windows服务。