1

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

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

由于ISession也是请求范围,我应该能够使用 Spring.NET 为我管理这些依赖项。

问题是 EventListener,就像,是一个不受请求范围限制IInterceptor的属性(ISessionFactory它是一个单例)。Web 对象范围之间的不匹配是有问题的。

我尝试了以下 XML 片段,但条件表达式总是产生 null。我认为这是由于 SpringEventListener在应用程序级别范围内创建对象,并且之前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实例被注入到当前的OSIVISession

4

1 回答 1

1

我认为你试图以错误的方式做到这一点。根据NHibernate 文档 EventListener,s 基本上应该被视为您的应用程序的单例。

即使您请求开始EventListener时使用.SessionFactoryHttpContext

相反,您应该在配置会话工厂时全局注册事件处理程序。如果您需要上下文信息,例如主体,您可以注入具有 (http) 上下文感知实现的依赖项或将其实现为环境上下文

从自定义侦听器中,您可以访问引发事件的会话。以这个实现为例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怎么做?

于 2012-01-20T14:11:38.160 回答