将 SharpArchitecture 的 NHibernateSession 与不同的线程结合使用
我在 ASP.NET MVC 3 应用程序中使用 SharpArchitecture。一切都运转良好。
使用 SharpArchitecture 的 NHibernateInitializer 为每个请求初始化一个新会话,如下所示:
protected void Application_BeginRequest(object sender, EventArgs e)
{
NHibernateInitializer.Instance().InitializeNHibernateOnce(InitializeNHibernateSession);
}
private void InitializeNHibernateSession(ISessionStorage sessionStorage)
{
NHibernateSession.ConfigurationCache = new NHibernateConfigurationFileCache(
new[] { "App.Core" });
NHibernateSession.Init(
sessionStorage,
new[] { Server.MapPath("~/bin/" + ApplicationSettings.Instance.NHibernateMappingAssembly) },
new AutoPersistenceModelGenerator().Generate(),
Server.MapPath("~/NHibernate.config"));
NHibernateSession.AddConfiguration(ApplicationSettings.NHIBERNATE_OTHER_DB,
new[] { Server.MapPath("~/bin/" + ApplicationSettings.Instance.NHibernateMappingAssembly) },
new AutoPersistenceModelGenerator().Generate(),
Server.MapPath("~/NHibernateForOtherDb.config"), null, null, null);
}
正如您所看到的,我们还访问了多个数据库。一切都很好。
这是我遇到问题的地方。
我需要启动一个单独的线程来执行数据库轮询机制。我的意图是做这样的事情:
protected void Application_Start()
{
....
ThreadingManager.Instance.ExecuteAction(() =>
{
// initialize another NHibernateSession within SharpArchitecture somehow
NHibernateInitializer.Instance().InitializeNHibernateOnce(InitializeNHibernateSession);
var service = container.Resolve<IDatabaseSynchronizationService>();
service.SynchronizeRepositories();
});
}
通过我的 SynchronizationService,一些存储库被调用。显然,当他们尝试访问会话时,会抛出异常,因为会话为空。
这是我的问题。我如何利用 SharpArchitecture 的 NHibernateSession 并以某种方式将它或它的副本在我的轮询线程中旋转?我希望这可以完成,而不必绕过使用 SharpArchitecture 使用的内置 SessionManagers 和 SessionFactories。
I'm using SharpArchitecture in an ASP.NET MVC 3 application. Everything works wonderfully.
Using SharpArchitecture's NHibernateInitializer to initialize a new Session per request like so:
protected void Application_BeginRequest(object sender, EventArgs e)
{
NHibernateInitializer.Instance().InitializeNHibernateOnce(InitializeNHibernateSession);
}
private void InitializeNHibernateSession(ISessionStorage sessionStorage)
{
NHibernateSession.ConfigurationCache = new NHibernateConfigurationFileCache(
new[] { "App.Core" });
NHibernateSession.Init(
sessionStorage,
new[] { Server.MapPath("~/bin/" + ApplicationSettings.Instance.NHibernateMappingAssembly) },
new AutoPersistenceModelGenerator().Generate(),
Server.MapPath("~/NHibernate.config"));
NHibernateSession.AddConfiguration(ApplicationSettings.NHIBERNATE_OTHER_DB,
new[] { Server.MapPath("~/bin/" + ApplicationSettings.Instance.NHibernateMappingAssembly) },
new AutoPersistenceModelGenerator().Generate(),
Server.MapPath("~/NHibernateForOtherDb.config"), null, null, null);
}
As you can see, we are also hitting multiple databases. All that's fine.
Here's where I run into an issue.
I need to spin up a separate thread to execute a database polling mechanism. My intention was to do something like this:
protected void Application_Start()
{
....
ThreadingManager.Instance.ExecuteAction(() =>
{
// initialize another NHibernateSession within SharpArchitecture somehow
NHibernateInitializer.Instance().InitializeNHibernateOnce(InitializeNHibernateSession);
var service = container.Resolve<IDatabaseSynchronizationService>();
service.SynchronizeRepositories();
});
}
And through my SynchronizationService, some repositories get called. Obviously when they attempt to access their session, an exception is thrown because the Session is null.
Here's my question. How can I leverage SharpArchitecture's NHibernateSession and somehow have it or a copy of it, spun up inside my polling thread? I am hoping this can be done without having to bypass using the built in SessionManagers and SessionFactories used by SharpArchitecture.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我假设
sessionStorage
是一个SharpArch.Web.NHibernate.WebSessionStorage
对象,对吗?如果是这样,那么问题不在于 NHibernate Session 为 null,而可能是在您的线程上,HttpContext.Current 为 null,并且 WebSessionStorage 对象依赖 HttpContext.Current 来完成其工作(请参阅 这段代码,特别是第 37 行,当从线程调用时,上下文为 null,因此会发生 null 异常)。我认为解决方案是编写一个不同的 SessionStorage 对象来检查 HttpContext.Current 是否为 null,如果是,则使用线程本地存储来存储 NHibernate Session(此解决方案来自于另一篇 StackOverflow 文章讨论了同样的事情:在Web应用程序Application_Start方法中初始化NServiceBus时出现NullReferenceException)
编辑
也许是这样的:
注意:当你完成你的操作时,你必须确保调用 NHibernateSession.CloseAllSessions()不过,请在线程上工作,因为当线程完成时,Application_EndRequest 不会被触发。
I assume that
sessionStorage
is aSharpArch.Web.NHibernate.WebSessionStorage
object, right? If so then the issue isn't so much that the NHibernate Session is null, it's probably that on your thread, HttpContext.Current is null, and the WebSessionStorage object relies on HttpContext.Current to do its work (see this code, particularly line 37, where, when called from a thread, context is null, so a null exception occurs).I think the solution would be to write a different SessionStorage object that checks to see if
HttpContext.Current
is null, and if it is, use thread local storage to store NHibernate Sessions in instead (this solution gleaned from this other StackOverflow article which talks about the same sort of thing: NullReferenceException when initializing NServiceBus within web application Application_Start method)EDIT
Something like this perhaps:
NOTE: You will have to make sure you call
NHibernateSession.CloseAllSessions()
when you have finished doing your work on the thread though, as Application_EndRequest won't get fired when your thread completes.