是。这是一个与我如何要求Castle Windsor解决我的ISession有关的问题,但我已经重读了5次这样的代码,并且仍然无法弄清楚它有什么问题。
下面是我相当标准的NHibernate工具,除了我注册的最后两个组件:
public class NHibernateFacility : AbstractFacility
{
protected override void Init()
{
var config = new Configuration().Configure();
Kernel.Register(
Component.For<ISessionFactory>()
.UsingFactoryMethod((kernel, context) => config.BuildSessionFactory()),
Component.For<ISession>()
.UsingFactoryMethod((kernel, context) => kernel.Resolve<ISessionFactory>().OpenSession())
.LifestylePerWebRequest(),
Component.For<IStatelessSession>()
.UsingFactoryMethod((kernel, context) => kernel.Resolve<ISessionFactory>().OpenStatelessSession())
.LifestylePerWebRequest(),
Component.For<StatefulSessionWrapper>().LifestylePerWebRequest(),
Component.For<StatelessSessionWrapper>().LifestylePerWebRequest()
);
}
}
StatefulSessionWrapper / StatelessSessionWrapper充当ISession / IStateless会话的...包装器,如下所示:
public class StatefulSessionWrapper : ISessionWrapper
{
public StatefulSessionWrapper(ISession session)
{
this.Session = session;
}
private readonly ISession Session;
#region ISessionWrapper Members
public ITransaction BeginTransaction()
{
return Session.BeginTransaction();
}
public ITransaction BeginTransaction(IsolationLevel isolationLevel)
{
return Session.BeginTransaction(isolationLevel);
}
public ITransaction Transaction { get { return Session.Transaction; } }
public bool IsConnected
{
get { return Session.IsConnected; }
}
public bool IsOpen
{
get { return Session.IsOpen; }
}
#endregion
}
这样,我可以使用单个动作过滤器,它只处理NHibernate会话的事务部分:
public class NHibernateActionFilter<T> : Castle.MonoRail.Framework.IFilter where T:ISessionWrapper
{
private readonly T NHibernateSession;
public NHibernateActionFilter(T session)
{
if (session != null)
NHibernateSession = session;
else
throw new NullReferenceException("Session is null");
}
#region IFilter Members
public bool Perform(ExecuteWhen exec, IEngineContext context, IController controller, IControllerContext controllerContext)
{
if (exec == ExecuteWhen.BeforeAction)
{
NHibernateSession.BeginTransaction();
return true;
}
if (exec == ExecuteWhen.AfterAction)
{
if (NHibernateSession.Transaction == null || !NHibernateSession.Transaction.IsActive)
return false;
if (context.LastException != null)
{
NHibernateSession.Transaction.Rollback();
return false;
}
else
{
NHibernateSession.Transaction.Commit();
return true;
}
}
return false;
}
#endregion
}
简单地使用它:
[Filter(ExecuteWhen.Always, typeof(NHibernateActionFilter<StatefulSessionWrapper>), ExecutionOrder = 1)]
[Filter(ExecuteWhen.BeforeAction, typeof(AuthenticationFilter), ExecutionOrder = 2)]
[Layout("Default"), Rescue("Default")]
public abstract class NHibernateController : SmartDispatcherController
{
public NHibernateController(ISession session)
{
this.NHibernateSession = session;
}
protected readonly ISession NHibernateSession;
..................
唯一的问题?
这是救援页面。请参阅下面的例外情况
的ObjectDisposedException
消息:会话已关闭!对象名称:'ISession'。
StackTrace:在NHibernate.Impl.AbstractSessionImpl.ErrorIfClosed() 在p:\ nhibernate-core \ src \ NHibernate \ Impl \ AbstractSessionImpl.cs:line 207点 NHibernate.Impl.AbstractSessionImpl.CheckAndUpdateSessionStatus()in p:\ nhibernate-core \ src \ NHibernate \ Impl \ AbstractSessionImpl.cs:第199行 在NHibernate.Impl.SessionImpl.BeginTransaction()中 p:\ nhibernate-core \ src \ NHibernate \ Impl \ SessionImpl.cs:第1456行 ADAutoTotal.Monorail.StatefulSessionWrapper.BeginTransaction()in C:\ Dropbox的\项目\ ADAutoTotal \ ADAutoTotal.Monorail \ StatefulSessionWrapper.cs:行 23点 ADAutoTotal.Monorail.NHibernateActionFilter`1.Perform(ExecuteWhen exec,IEngineContext上下文,IController控制器, IControllerContext controllerContext)in C:\ Dropbox的\项目\ ADAutoTotal \ ADAutoTotal.Monorail \ NHibernateActionFilter.cs:行 31点 Castle.MonoRail.Framework.Controller.ProcessFilter(ExecuteWhen何时, FilterDescriptor desc)in C:\ Dropbox \ Projects \ Monorail \ castleproject-MonoRail-98c93ac \ castleproject-MonoRail-98c93ac \ MR2 \ src \ Castle.MonoRail.Framework \ Controller.cs:line 2099 at at Castle.MonoRail.Framework.Controller.ProcessFilters(IExecutableAction 动作,执行时何时) C:\ Dropbox \ Projects \ Monorail \ castleproject-MonoRail-98c93ac \ castleproject-MonoRail-98c93ac \ MR2 \ src \ Castle.MonoRail.Framework \ Controller.cs:line 2054 at at Castle.MonoRail.Framework.Controller.RunBeforeActionFilters(IExecutableAction 动作,布尔&amp;取消)in C:\ Dropbox \ Projects \ Monorail \ castleproject-MonoRail-98c93ac \ castleproject-MonoRail-98c93ac \ MR2 \ src \ Castle.MonoRail.Framework \ Controller.cs:line 1953 at at Castle.MonoRail.Framework.Controller.RunActionAndRenderView()中 C:\ Dropbox \ Projects \ Monorail \ castleproject-MonoRail-98c93ac \ castleproject-MonoRail-98c93ac \ MR2 \ src \ Castle.MonoRail.Framework \ Controller.cs:1622行
因此,很明显NHibernateActionFilter获得了一个封闭的会话。但据我说,它不应该。 HALP。
答案 0 :(得分:1)
嗯,事实证明,我忘了添加我的动作过滤器他们正确的生活方式,因此让温莎让他们单身......