我的存储库都在构造函数中使用ISession:
protected Repository(ISession session) { this.session = session; } private readonly ISession session;
在使用StructureMap的Asp.Net MVC应用程序中,我如何在StructureMap注册表中设置ISession?我还需要将SessionFactory添加到容器中吗? FluentNHibernate改变了什么吗?
解决方法
您应该使用工厂方法注册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程序集中,所以我不应该每次都重新实现它.
编辑:现在,在Web应用程序中使用ISession:
>在结构图中注册SessionFactoryAggregator(生命周期可以是单例).
>在Snstrucure映射中注册SessionAggregator并将其生命周期设置为InstanceScope.Hybrid.
>在每个请求结束时,您需要通过调用HttpContextBuildPolicy.DisposeAndClearAll()来处置会话
代码可能如下所示:
// The Registry in StructureMap ForRequestedType<ISessionFactory>() .CacheBy(InstanceScope.Singleton) .TheDefaultIsConcreteType<SessionFactoryAggregator>(); ForRequestedType<ISession>() .CacheBy(InstanceScope.Hybryd) .TheDefaultIsConcreteType<SessionAggregator>(); // Then in EndRequest call HttpContextBuildPolicy.DisposeAndClearAll()