【发布时间】:2015-03-20 22:48:10
【问题描述】:
我正在为 ASP.NET MVC 开发一个 Web 应用程序。使用基于 nHibernate 与数据存储库进行交互。存储库通过 Unity 实例化。每个请求到存储库解析 ISession。
现在我需要在项目中添加在后台执行定期计划任务的爬虫。要实现爬虫选择 Quartz.NET。一个项目可以有多个不同的 walker,同时通过存储库与数据库交互,如果与他们的任务执行相匹配。
问题是爬虫必须创建另一个会话,因为它基于一个请求解决方案不起作用(没有网络请求)。它实现了一个解决方案,我在其中注册了两个不同的 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)
{
}
}
【问题讨论】:
标签: asp.net-mvc nhibernate fluent-nhibernate unity-container quartz.net