using (Fluent) NHibernate with StructureMap (or any IoCC) - c#

On my quest to learn NHibernate I have reached the next hurdle; how should I go about integrating it with StructureMap?
Although code examples are very welcome, I'm more interested in the general procedure.
What I was planning on doing was...
Use Fluent NHibernate to create my class mappings for use in NHibs Configuration
Implement ISession and ISessionFactory
Bootstrap an instance of my ISessionFactory into StructureMap as a singleton
Register ISession with StructureMap, with per-HttpRequest caching
However, don't I need to call various tidy-up methods on my session instance at the end of the HttpRequest (because thats the end of its life)?
If i do the tidy-up in Dispose(), will structuremap take care of this for me?
If not, what am I supposed to do?
Thanks
Andrew

I use StructureMap with fluent-nhibernate (and NH Validator) in 3 of my current projects. 2 of those are ASP MVC apps and the third is a WCF web service.
Your general strategy sounds about right (except you won't be making your own Session or SessionFactory, as was already pointed out in comments). For details, snag my configuration code from here:
http://brendanjerwin.github.com/development/dotnet/2009/03/11/using-nhibernate-validator-with-fluent-nhibernate.html
The post is really about integrating NH Validator and Fluent-NHibernate but you can see exactly how I register the session factory and ISession with StructureMap in the "Bonus" section of the post.
RE: Tidy up: You should try and always work within a transaction and either commit or roll-back the transaction at the end of your unit of work. NH only utilizes SQL Connections when it needs them and will take care of the cleanup of that limited resource for you. Normal garbage collection will take care of your sessions themselves.
The Session Factory is a very expensive object that you will want to only initialize once and keep around for the life of your app.

I've not used structure map but maybee I can still help guide you in the right direction. Fluent nHibernate is awsome good choice over the hbm files.
As for the http request, you do not need to ensure that you close the session when the http request ends. If you don't you'll end up leaking nHibernate session. I'm not sure if structure map will handle this for you, what I've done is I have an http module which closes the session.
One thing to note though that bite me, is that you will make to sure you wrap all your data access in a transaction and ensure nHibernate actually commits its changes. If you do this as part of your session close, you could miss the chance to handle errors. I'm curious to hear what you ended up having to do to get this workign.

Related

How to implement Session Per Conversation pattern with WebAPI/ NHibernate

I have an MVC project that I exclusively employ a custom "Unit Of Work" pattern that uses NHibernate on the back end, which I expose to my application as IUnitOfWork and IUnitOfWorkFactory interfaces; These interfaces are injected as my NHibernate implementations via Ninject.
I use my UOW in a modified "session per request" style... I explicitly generate my IUnitOfWork from my injected IUnitOfWorkFactory when I need to perform database operations; it seems much easier to keep the CRUD where it belongs (out of my views and controllers) and effectively prevents accidental N+1 coding issues. Of course, it's a little harder to implement, but to date, I've been pretty happy with it.
Now I want to implement a WebAPI presenting IQueryable<Entity>-style REST calls, and my UOW pattern isn't digging it. The Queryables invariably blow up, attempting to invoke a disposed NHibernate session.
I've read some stuff online about how to implement a DelegatingHandler to manage the session for a WebAPI call... but I see several problems:
It seems that all the examples are assuming a "Session per Request" pattern... which is by far the most popular pattern, but not exactly one which I am using, so I'm not sure that is even the proper direction to go.
It's not clear how I can implement this handler exclusively for these Web API calls.
I've seen a lot of suggestions to use a "Session per Conversation" pattern which is potentially even longer-lived than the "Session per Request" pattern... it sounds like it might be appropriate for this endeavor, but the documentation on how to implement it is a little sparse.
All the sample implementations I've seen pretty much tightly couple the NHibernate ISession to the web application, using a built-in NHibernate mechanism (CurrentSessionContext.Bind(ISession)); I'd much rather reference my IUnitOfWork interface, and trust it to maintain the session it needs to.
So my question is, how can I implement a IQueryable<Entity> RESTful API using my own IUnitOfWork interface going against loosely-coupled NHibernate back-end?
You would face the same problem with a straightforward session-per-request implementation. For example:
// GET api/companies
public IQueryable<Company> GetCompanies()
{
return _session.Query<Company>();
}
I usually wrap all database operations, including selects, in a transaction but because query execution is deferred I can't do it in this method. It is possible to do so by creating an ActionFilter and overriding OnActionExecuted but the difficulty is gaining a reference to the ISession or your IUnitOfWork implementation in the filter. There are examples of how to accomplish this using Ninject and other dependency injection frameworks on the web.
Personally I don't see the value of abstracting the ISession, especially in Web API where it would be very rare to have a resource that did not perform a database operation. Session-per-conversation is definitely not a good pattern for this; it generally refers to keeping a session open over multiple server round trips.
My preferred architecture is to use Ninject to manage ISessionFactory and ISession lifetime (singleton and per-request, respectively) and to inject the ISession into the Api controllers. But you could also inject it into a repository or unit of work implementation.

Is using a well know Singleton pattern to save state in a stateless MVC application considered a good approach?

I need to save some session/user related information in my MVC project. Since it should be unique and available throughout the lifetime of the session, I thought about "session-wide" singleton. I found several posts on this subject (for example here, here or here) but then I remembered reading this post about not using the Session object in a MVC application. Since this sounds like a generally bad idea, I thought about using the 4th version of Jon Skeet's singleton. In a couple of quick tests I wasn't able to see any violation of the singleton pattern per user session (i.e. only one object for every session was created). I might have missed something or might not have tested it correctly.
Is it safe to use this pattern for a session singleton in a MVC project (without saving the object in HttpContext.Current.Session or HttpContext.Current.Items)?

NHibernate session closing unexpectedly

I am using a MVC4, C#, Castle Windsor, fluentnhibernate stack for my web application, which generally works very well.
Its only occasionally that I get an error related to nHibernate something along the lines of:
Invalid attempt to call Read when reader is closed.
or
Internal connection fatal error.
This usually rears its ugly head when I do multiple calls, in very close succession.
Currently I am replicating it while doing multiple ajax gets, from JQuery.
What I suspect the problem is, is with my NHibernate session management.
The only thing I can think of is that the calls are someone using the same session, the first one completes and closes it, then the following call is unable to complete.
This shouldn't be possible due to the way my sessions are handled like this:
Kernel.Register(
Component.For<ISessionFactory>()
.UsingFactoryMethod(_ => config.BuildSessionFactory()),
Component.For<ISession>()
.UsingFactoryMethod(k => k.Resolve<ISessionFactory>().OpenSession())
.LifestylePerWebRequest());
Should be one session per request right?
How else, or where else can I look for the problem? I am quite stuck.
Of course solved this a few minutes later, but the answer was an eye opener for me.
This answer led me down the right path.
While all of my Repositories, Manager and other layers were installed with the correct lifestyle using Castle Windsor, there was one that wasn't.
I was doing a Repository call from an ActionFilter, all of my action filters are invoked through an ActionInvoker class which was registered incorrectly as Singleton, which resulted in my errors.
container.Register(Component.For<IActionInvoker>()
.ImplementedBy<WindsorActionInvoker>()
.LifeStyle.***Singleton***);
Should of course be
container.Register(Component.For<IActionInvoker>()
.ImplementedBy<WindsorActionInvoker>()
.LifeStyle.Transient);
Just another reminder to pay closer attention to those Lifestyles.

ORM Repository Pattern

This is more of a question where I am looking for opinions. I am working on a project that uses both NHibernate and EntityFramework (this is by design, wanted flexibility). So, I went ahead and started working on a Repository pattern, but came across a slight dilemma.
Basically, I wanted to know what you guys think about the following areas:
Should the Repository be a singleton? - This will allow me to keep the sessions opened, but at the same time, I think it's going to keep connections opened to the database. For NHibernate, the ORM can only gurantee an objet is the same within the same session. This is ideal for easy coding, but there are definatly ways to overcome this using keys and overriding the GetHashCode and Equals methods.
If it's not a singleton (or even if it is), should I be closing the connections as soon as they are used? For NHibernate, that means closing the session each time the Repository is "Disposed", which is after every use.
Have you implemented a Repository pattern for either NHibernate or EF 4.0 and found any useful ideas?
Don't code the creation of singletons yourself (ie the singleton pattern itself), use an IOC framework like StructureMap to handle the Lifecycle management of objects.
This we can't answer. If it's singleton it must be thread safe in regards to the resources it manages internally (like a connection pool of DB live connections). Threadsafe code isn't trivial.
This we can't answer. It depends on how you act with your model. It also depends whether you want people to be able to read through a DataReader which requires an active connection to the database. This also affects things like lazy loading which requires active sessions which becomes a nightmare with databinding.
Here's everything I've come up with in regards to creating a repository pattern for NH: Creating a common generic and extensible NHiberate Repository version 2
First question, does it have to be NHibernate? Why not take a look at using EF4 with an IoC, my favorite is StructureMap, then you non longer have to worry about making your repository singleton as StructureMap gives options to keep the scope open by request, by HttpContext, by Hybrid. You of course have the option to use the Singleton pattern with your Repository I'm just not sold on it being a viable option in a case like this.
Hope that helps more than it confuses you.

NHibernate session management with RIA-services

How should I manage my session? I've seen some examples where the session is created in the constructor of the domainservice and destroyed in the dispose method, but this seems like a bad idea.
Would appreciate help here because I can't find any information.
I don't know RIA Services very well but it's based on WCF so maybe you can use the pattern of one session for each Operation, like in web you can use the pattern Session per Request ?
http://www.google.ca/search?hl=en&safe=off&q=WCF+Nhibernate+operation+context&aq=f&aqi=&aql=&oq=&gs_rfai=
and the first response give some code :
http://realfiction.net/go/133
The next version of NHibernate, the integration of WCF should be built-in, here'sthe source code from the trunk :
https://nhibernate.svn.sourceforge.net/svnroot/nhibernate/trunk/nhibernate/src/NHibernate/Context/WcfOperationSessionContext.cs

Categories