Injecting ISession Into My Repositories Using Structuremap in a Asp.Net MVC Application

后端 未结 2 1092
灰色年华
灰色年华 2021-01-01 06:11

My repositories all take ISession in the constructor:

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


        
相关标签:
2条回答
  • 2021-01-01 06:33

    This question & answers might help you.

    One way to go - steal nhibernate session management from "S#arp Architecture". Works great.

    0 讨论(0)
  • 2021-01-01 06:41

    You should register ISession using a factory method.

    Another options (not always the best, but easy to use) is to:

    Implement ISession and ISessionFactory interfaces (SessionProxy and 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                
    }
    

    This way you can just register ISession (implemented by SessionAggregator) and ISessionFactory (SessionFactoryAggreagator) and any DI framework will resolve ISession easily.

    This is good if your DI does not support factory method (I don't know if Structure Map does).

    I have added these implementation to my Commons assembly so I should not reimplement it every time.

    EDIT: Now, to make use of ISession in web application:

    1. Register SessionFactoryAggregator in the structure map (life time can be singleton).
    2. Register SessionAggregator in Snstrucure map and set its lifetime to InstanceScope.Hybrid.
    3. At the end of each request you need to dispose the session by calling HttpContextBuildPolicy.DisposeAndClearAll()

    The code can look like:

    // The Registry in StructureMap
    ForRequestedType<ISessionFactory>()
            .CacheBy(InstanceScope.Singleton)
            .TheDefaultIsConcreteType<SessionFactoryAggregator>();
    
    ForRequestedType<ISession>()
            .CacheBy(InstanceScope.Hybryd)
            .TheDefaultIsConcreteType<SessionAggregator>();
    
    // Then in EndRequest call
    HttpContextBuildPolicy.DisposeAndClearAll()
    
    0 讨论(0)
提交回复
热议问题