How can I implement an NHibernate session for each request without NHibernate dependency?

I asked this question before, but I'm still struggling to find an example on which I can plunge (please don't just tell me to look at the S # arp Architecture architecture project, at least in some directions).

So far, I have achieved almost ignorance of ignorance in my web project. My repository classes (in my data project) accept ISession in the constructor:

public class ProductRepository : IProductRepository { private ISession _session; public ProductRepository(ISession session) { _session = session; } 

In my global.asax, I expose the current session and create and delete the session at beginrequest and endrequest (this is where I have a dependency on NHibernate):

  public static ISessionFactory SessionFactory = CreateSessionFactory(); private static ISessionFactory CreateSessionFactory() { return new Configuration() .Configure() .BuildSessionFactory(); } protected MvcApplication() { BeginRequest += delegate { CurrentSessionContext.Bind(SessionFactory.OpenSession()); }; EndRequest += delegate { CurrentSessionContext.Unbind(SessionFactory).Dispose(); }; } 

And finally, my StructureMap registry:

  public AppRegistry() { For<ISession>().TheDefault .Is.ConstructedBy(x => MvcApplication.SessionFactory.GetCurrentSession()); For<IProductRepository>().Use<ProductRepository>(); } 

It would seem that I need my own common implementations of ISession and ISessionFactory, which I can use in my web project and implement in my repositories?

So, just to clarify - I'm using NHibernate at my repository level and want to use a session request (http). Therefore, I inject ISession into my repository constructors (using the structure structure). Currently, to create and host sessions in each request, I need to reference NHibernate from my web project. This is a dependency that I would like to remove.

Thanks Ben

+7
dependency-injection asp.net-mvc nhibernate structuremap
source share
3 answers

Why don't you create an IHttpModule and don't do your creation and place it there (maybe in the Begin_Request and End_Request events), but put your IHttpModule in a project that has your NHibernate dependency. eg.

 namespace MyWebApp.Repository.NHibernateImpl { public class NHibernateModule : IHttpModule { public void Init(HttpApplication context) { context.BeginRequest += new EventHandler(Context_BeginRequest); context.EndRequest += new EventHandler(Context_EndRequest); } private void Context_BeginRequest(object sender, EventArgs e) { // Create your ISession } private void Context_EndRequest(object sender, EventArgs e) { // Close/Dispose your ISession } public void Dispose() { // Perhaps dispose of your ISessionFactory here } } } 

Perhaps the best way, I am also interested in learning about this, so what are any alternative suggestions?

+3
source share

In my opinion, you should accept ISession and work with it directly. The problem with many implementations for each request is that they delay the database changes until the end of the HTTP request. If the transaction failed, all you can do at this point is the direct user on the common error page. It’s much better to manage the transaction on the page so that you can more effectively catch and handle errors. If you take this route, you need to access the ISession or shell to manage the transaction.

Also, at some point your application will probably need to use the properties or methods provided by ISession, especially Merge and Load.

+2
source share

Thanks for helping everyone. A little more research led me to the NHibernate Burrow project.

From the FAQ project ( http://nhforge.org/wikis/burrow/faq.aspx ):

Burrow is a lightweight middleware designed to support .Net applications using NHibernate (possibly also referred to as NH in this article) as an ORM framework. Using Asp.net with NHibernate can be a problem because NHibernate is a stateful environment, while Asp.net is a stateless system. Burrow can help resolve this conflict by providing advanced and intelligent session / transaction management and others.

I had to jump over several hoops to make it work in my project. Since the current version uses the old version of NHibernate, I had to download the latest source from an external line, open it in VS, add links to the latest version of NHibernate and recompile (fortunately, no errors).

I tested NHibernate Burrow in several ways.

1) Keep typing ISession in my repositories

To do this, I had to add links to NHibernate, NHibernate.Burrow and NHibernate.Burrow.WebUtil in my MVC project.

In web.config, I had to install Burrow (see http://nhforge.org/wikis/burrow/get-started.aspx ), and then add the following to my StructureMap registry:

  For<ISession>() .TheDefault.Is .ConstructedBy(x => new NHibernate.Burrow.BurrowFramework().GetSession()); 

I like this approach, as it means that my repositories (or controllers) are not related to Burrow. I don’t really like the fact that I have to reference these three assemblies in my web project, but at least I lose the session management code - all this is handled by Burrow.

2) A second approach would be to install ISession in my repository constructors as follows:

  public ProductRepository() : this(new BurrowFramework().GetSession()) { } public ProductRepository(ISession session) { _session = session; } 

I can still override ISession to check my repositories. I then have a direct dependence on Burrow, but perhaps this is not so bad?

On the plus side, the only build I need to reference from my web project is NHibernate.Burrow.WebUtils.

Interest in which of the two people will go and why.

0
source share

All Articles