在Asp.Net MVC应用程序中使用Structuremap将ISession注入我的存储库

时间:2009-08-18 22:24:55

标签: asp.net-mvc nhibernate fluent-nhibernate structuremap

我的存储库都在构造函数中使用了ISession:

protected Repository(ISession session)
{
     this.session = session;
}
private readonly ISession session;

在使用StructureMap的Asp.Net MVC应用程序中,我如何在StructureMap注册表中设置ISession?我还需要将SessionFactory添加到容器中吗? FluentNHibernate会改变一切吗?

2 个答案:

答案 0 :(得分:1)

您应该使用工厂方法注册ISession。

另一种选择(并非总是最好,但易于使用)是:

实现ISession和ISessionFactory接口(SessionProxy和SessionFactoryProxy)。

public class SessionAggregator : ISession {
    protected ISession session;

    public SessionAggregator(ISessionFactory theFactory) {
        if (theFactory == null)
            throw new ArgumentNullException("theFactory", "theFactory is null.");
        Initialise(theFactory);
    }

    protected virtual void Initialise(ISessionFactory factory) {
        session = factory.OpenSession();
    }
    // the ISession implementation - proxy calls to the underlying session  
 }

public class SessionFactoryAggregator : ISessionFactory {
    protected static ISessionFactory factory;
    private static locker = new object();
    public SessionFactoryAggregator() {
            if (factory == null) {
              lock(locker) {
                if (factory == null)
                  factory = BuildFactory();
              }
            }
    }

    // Implement the ISessionFactory and proxy calls to the factory                
}

这样您就可以注册ISession(由SessionAggregator实现)和ISessionFactory(SessionFactoryAggreagator),任何DI框架都可以轻松解析ISession。

如果您的DI不支持工厂方法(我不知道结构图是否有效),这很好。

我已将这些实现添加到我的Commons程序集中,所以我不应该每次都重新实现它。

编辑:现在,在网络应用程序中使用ISession:

  1. 在结构图中注册SessionFactoryAggregator(生命时间可以是单例)。
  2. 在Snstrucure地图中注册SessionAggregator并将其生命周期设置为InstanceScope.Hybrid。
  3. 在每个请求结束时,您需要通过调用HttpContextBuildPolicy.DisposeAndClearAll()
  4. 来处置会话

    代码看起来像:

    // The Registry in StructureMap
    ForRequestedType<ISessionFactory>()
            .CacheBy(InstanceScope.Singleton)
            .TheDefaultIsConcreteType<SessionFactoryAggregator>();
    
    ForRequestedType<ISession>()
            .CacheBy(InstanceScope.Hybryd)
            .TheDefaultIsConcreteType<SessionAggregator>();
    
    // Then in EndRequest call
    HttpContextBuildPolicy.DisposeAndClearAll()
    

答案 1 :(得分:0)

This问题&amp;答案可能对你有帮助。

一种方法 - 从"S#arp Architecture"窃取nhibernate会话管理。效果很好。