1

我在ASP.NET应用程序中使用Spring.NET 1.3.2,NHibernate 3.1和OSIV模式。Spring.NET + NHibernate +请求作用域对象不能很好地协作

我有一个自定义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> 

所以我的要求是:

  1. 配置自定义EventListener对象春,使其产生在每个请求的基础必须发生

  2. EventListener实例下旬足够请求生命周期,以便HttpContext.Current.Items ['Princpial']已由自定义IHttpModule填充

  3. EventListener实例被注入到当前OSIV ISession

回答

1

我想你想这样做周围的错误的方式。根据NHibernate documentationEventListener应基本上被认为是你的应用程序的单身人士。

即使你与SessionFactory注册您的自定义EventListener,说在请求开始,你还有没有保证,这个监听器将只收到在当前HttpContext引发的事件。

相反,您应该在配置会话工厂时在全局注册您的事件处理程序。如果需要上下文信息(如主体),则可以使用(http)上下文感知实现注入依赖关系,或者将其实施为ambient context

从自定义侦听器中,您可以访问引发该事件的会话。就拿这个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

相关问题