Spring.NET + NHibernate +请求范围内的对象不能很好地协同工作

时间:2012-01-04 04:07:07

标签: nhibernate dependency-injection spring.net open-session-in-view

我在ASP.NET应用程序中使用Spring.NET 1.3.2,NHibernate 3.1和OSIV模式。

我有一个自定义EventListener需要请求作用域,因为它使用了 HttpContext.Current.Items作为构造函数依赖。

由于ISession也是请求作用域,我应该可以使用Spring.NET来管理这些依赖项。

问题是EventListenerIInterceptor一样,是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>

所以我的要求是:

  1. 在Spring中配置自定义EventListener对象,以便在每个请求的基础上创建

  2. EventListener实例化必须在请求生命周期中发生得足够晚,以便HttpContext.Current.Items ['Princpial']已由自定义IHttpModule填充

  3. EventListener实例注入当前的OSIV ISession

1 个答案:

答案 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应该怎么做?