I'm somewhat new to the MVC framework and in accordance with the following post:
NHibernate with StructureMap I am not sure how to actually get the HttpContextScoped ISession in my controller?
I'm sure there is a simple way to do this but I am unsure.
Also, it's a small project and I don't want to go overboard with Enterprise Design Patterns.
Thanks!
did you try writting this line in your action method of your controller ?
ISession session = ObjectFactory.GetInstance<ISession>();
Related
I am using Castle Windsor for my IoC along with NHIbernate in an ASP.NET MVC app. It works great registered as follows:
container.Register(Component.For<ISessionFactoryBuilder.().ImplementedBy<SessionFactoryBuilder>().LifestyleSingleton());
// Register the NHibernate session factory as a singleton using custom SessionFactoryBuilder.BuildSessionFactory method.
container.Register(Component.For<ISessionFactory>().UsingFactoryMethod(k => k.Resolve<ISessionFactoryBuilder>().BuildSessionFactory("ApplicationServices")).LifestyleSingleton());
container.Register(Component.For<ISession>().UsingFactoryMethod(k => k.Resolve<ISessionFactory>().OpenSession()).LifestylePerWebRequest());
However, I want to introduce an NHibernate IInterceptor in order to provide easy auditing. Typically I've used a NHibernate session manager in which it's easy to pass in an interceptor later on because SessionFactory.OpenSession(...) would typically be called in Begin_Request as opposed to "sort of" during component registration (which is in App_Start). Unfortunately, the LifestylePerWebRequest module can't be accessed at that point so for i.e., the following understandably fails:
container.Register(Component.For<IInterceptor>().ImplementedBy<ChangeAuditInfoInterceptor>().LifestylePerWebRequest());
var interceptor = container.Resolve<IInterceptor>();
container.Register(Component.For<ISession>().UsingFactoryMethod(k => k.Resolve<ISessionFactory>().OpenSession(interceptor)).LifestylePerWebRequest());
What would be the best way to introduce an NHibernate Interceptor (which is usually inserted in SessionFactory.OpenSession(IInterceptor) when using this approach to NHibernate session management with Castle Windsor?
As stated in the comments, you should put the code to instantiate your interceptor in the lambda. This way, the code would execute on the right time :
container.Register(Component.For<ISession>()
.UsingFactoryMethod(k => k.Resolve<ISessionFactory>()
.OpenSession(container.Resolve<IInterceptor>()))
.LifestylePerWebRequest());
My application is interacting with two separate database. I want to inject session factory with spring.net as usually. when I am creating 2 session factory with two separate dbProviders , it is showing error. Is there any way to accomplish this task ?
You have to use a DelegatingLocalSessionFactory object, available for Spring.NET 1.3.1 and up. According to the docs:
due to variations in the NHibernate project's ISessionFactory API, this approach is only supported under NHibernate 2.1.2 and NHibernate 3.0
I'm not sure about NHibernate > 3.0.
I solved it by creating my own transaction API with Spring AOP.
I want to use fluent-nhibernate to query my data, but when a entity gets saved, it should not be written into the database via insert/update. Instead, I want to (better: have to) serialize that object and send it to a webservice (which will map that object to a 3rd-party class that will trigger some important business-logic).
Is such behaviour possible to implement with nhibernate (call a custom method instead of update on saving)?
I would recommend creating a IRepository interface and hiding the webservice and Nhibernate functionality behind that. You could possibly use NHibernate interceptors for this, but it doesn't sound like a clean solution. Personally, I would hate to find Web service code hidden in one of Nhibernate interceptors.
We decided to use a SaveOrUpdateEventListener for this task.
I Have been struggeling with NHibernate session management and have now ended up with two possible solutions to meet a session per web request.
I'm using Windsor for IoC in an ASPNET mvc project
First solution is to open a session in begin_request and close/dispose it again in end_request. In Windsor setup I would have
container.Register(Component.For().UsingFactoryMethod(() => SessionFactory.GetCurrentSession()).LifeStyle.Transient;
This solution creates the session per request and shares it through GetCurrentSession.
The second solution is to use Windsor like
container.Register(Component.For().UsingFactoryMethod(() => SessionFactory.OpenSession()).LifeStyle.PerWebRequest);
This sould also give me an session per web request and support constructor injection. It's a bit more simpel, but I need a second opinion.
Please let me know what you would prefer to use,
best regards
Rasmus
I don't recommend any of those two solutions. Instead of trying to reinvent the wheel, use the NHibernate facility.
I use a unit of work, which I configure per web request in the container. The unit of work does not just create a session, but it also commits and rolls back transactions. The main reason to use a unit of work is to make the database more stable. More information about the unit of work pattern can be found on here.
public interface INHiberanteUnitOfWork
{
ISession session { get; }
void Commit();
void RollBack();
}
How do I manage session if I am using Castle Active Record over nHibernate. Basically I can manage the life cycle of ISession on my own if I am using nHibernate directly. But when I am using Castle AR it does not give me a way to manage the life cycle of the session. I want to use single Session per thread.
I am using Castle AR in a WCF service and would like to use Session per WCF Request.
Instead of using ISession, in Castle ActiveRecord you want SessionScope:
using(new SessionScope())
{
; // do work here
}
If you need access to the ISession inside the SessionScope for some reason, you can do this:
ISession dbSession = Castle.ActiveRecord.ActiveRecordMediator
.GetSessionFactoryHolder().CreateSession(
typeof(Castle.ActiveRecord.ActiveRecordBase));
More documentation is here:
http://www.castleproject.org/activerecord/documentation/trunk/usersguide/scopes.html#sess_scope
and here:
http://www.castleproject.org/activerecord/documentation/trunk/manual/scopes.html
I assume you are working in a web app. Is that not the case?
There are a couple of ways to do it - Castle AR documentation
The simplest way is to the use SessionScopeWebModule to give a session per request.