我在ASP.NET应用程序中使用Spring.NET 1.3.2,NHibernate 3.1和OSIV模式。
我有一个自定义EventListener
需要请求作用域,因为它使用了
HttpContext.Current.Items作为构造函数依赖。
由于ISession
也是请求作用域,我应该可以使用Spring.NET来管理这些依赖项。
问题是EventListener
与IInterceptor
一样,是ISessionFactory
的属性,不请求作用域(它是单身)。 Web对象范围之间的不匹配是有问题的。
我尝试了以下XML代码段,但条件表达式总是产生null。我认为这是由于Spring在应用程序级别范围内创建EventListener
对象,并且在HttpContext.Current.Items
有机会填充之前。
<object id="EventListener" scope="request" type="MyEventListener,DAL">
<constructor-arg index="0" expression="T(System.Web.HttpContext).Current.Items.Contains('Principal')?T(System.Web.HttpContext).Current.Items['Principal']:null"/>
</object>
所以我的要求是:
在Spring中配置自定义EventListener
对象,以便在每个请求的基础上创建
EventListener
实例化必须在请求生命周期中发生得足够晚,以便HttpContext.Current.Items ['Princpial']已由自定义IHttpModule填充
将EventListener
实例注入当前的OSIV ISession
答案 0 :(得分:1)
我认为你试图以错误的方式做这件事。根据{{3}} EventListener
,基本上应该将您的应用视为单身人士。
即使您使用EventListener
注册自定义SessionFactory
,也就是说在请求开始时,您仍无法保证此侦听器仅接收事件在当前HttpContext
中提出。
相反,您应该在配置会话工厂时全局注册您的事件处理程序。如果您需要上下文信息(例如主体),则可以使用(http)上下文感知实现注入依赖项,或将其实现为NHibernate documentation。
从自定义侦听器中,您可以访问引发该事件的会话。比如这个ILoadEventListener
实现:
public class CustomLoadEventListener : ILoadEventListener
{
private IPrincipalProvider _principalProvider;
public CustomLoadEventListener(IPrincipalProvider provider)
{
_principalProvider = provider;
}
public void OnLoad(LoadEvent @event, LoadType loadType)
{
var sessionThatRaisedTheEvent = @event.Session;
var principalForTheCurrentContext = _principalProvider.GetCurrentPrincipal();
}
}
public interface IPrincipalProvider
{
IPrincipal GetCurrentPrincipal();
}
public class HttpContextPrincipalProvider : IPrincipalProvider
{
public IPrincipal GetCurrentPrincipal()
{
return System.Web.HttpContext.Current.User;
}
}
这可能不是你希望得到的答案,但IMO所要求的是与基础设施作斗争,我通常会尽量避免。
如果您发布有关您要实现的目标的更多详细信息,我们可能会提出更好的解决方案。您的EventListener
应该怎么做?