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

感情迁移 提交于 2020-01-10 15:40:13

问题


My repositories all take ISession in the constructor:

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

In an Asp.Net MVC application, using StructureMap, how would I go about setting up ISession in my the StructureMap Registry? Would I need to to add SessionFactory to the container also? Does FluentNHibernate change things?


回答1:


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()



回答2:


This question & answers might help you.

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



来源:https://stackoverflow.com/questions/1296901/injecting-isession-into-my-repositories-using-structuremap-in-a-asp-net-mvc-appl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!