Thanks a lot Jason for you help. Sorry for my disturbance. ((just a point to them who would like to use NH 2.1.2.4000 and latest Castle versions, NHibernate.ByteCode.Castle source code should be built by the latest version of Castle.Core and Castle.DynamicProxy2.))
I use IHttpModule to open/close session but I get "Session Closed" error. 1. web.config: I have current_session_context_class = web & <add name="SessionScope" type="MyPackage.Helper.SessionScope, MyPackage"/> in my httpModule section 2. I have a daoFactory which is registered in container. this daoFactory initialize all my DAOs. (But I do not have registered my dao in the container directly. DAO classes are for CRUD operation) 3. I have some services classes which has some dao as object for other process with retrieved data from DAOs. In these services classes I have initialized each dao through daofactory 4. All my daos is inserted in castle section of web.config I do not know why I get "session closed error". The only thing I can guess is registration in container which I have some trouble to understand. SessionScope (that implements IHttpModule) should retrieve and close session byself? or? Thanks for any help Regards Sheri On 25 Jan, 14:49, Jason Meckley <[email protected]> wrote: > Sheri, this has been my approach with registering NH in Windsor. > > public NhibernateFacility : AbstractFacility > { > public override void Init() > { > var configuration = new Configuration().Configure(); > var factory = configuration.BuildSessionFactory(); > Kernel.AddComponentInstance("nhibernate_configuration", > configuration); > Kernel.AddComponentInstance("session_factory", ); > Kernel.Resolvers.Add(NhibernateSessionResolver(Kernel)); > //I could also use the factory method to resolve the session, > but > that can cause a memory leak if i don't also implement > //a custom lifecyle for it. It's easier just to resolve the > session > with sub dependency resolver. > //It's also easier to test in isolation. > } > > } > > public NhibernateSessionResolver : ISubDependencyResolver > { > private readonly IKernel kernel; > > public NhibernateSessionResolver(IKernel kernel) > { > this.kernel = kernel; > } > > public bool Resolve(CreationContext context, ISubDependencyResolver > contextHandlerResolver, ComponentModel model, DependencyModel > dependency) > { > return kernel.Resolve<ISessionFactory>().GetCurrentSession(); > } > > public bool CanResolve(CreationContext context, > ISubDependencyResolver contextHandlerResolver, ComponentModel model, > DependencyModel dependency) > { > return > typeof(ISession).IsAssignableFrom(dependency.TargetType); > } > > } > > new Configuration().Configure() will automatically load the > hibernate.config file from the root directory of the project. part of > this configuration will be a property defining the > CurrentSessionContext web, thread, map, etc. the best choice for this > will depend on where you are using this configuration. With this is > place I can now inject a session into other objects. > > public class Foo > { > private readonly ISession session; > > public Foo(ISession session) > { > this.session = session; > }} > > I can then register Foo into the container as well with a transient > lifestyle and all will be resolved for me automatically. > > The next piece to consider is managing when to open/close the session. > I work with web applications and use an HttpModule to manage the > session. > public class SessionScope : IHttpModule > { > public void Init(HttpApplication context) > { > context.BeginRequest += OpenSession; > context.EndRequest += CloseSession; > } > > private void OpenSession(object sender, EventArgs e) > { > var factory = WindsorContainerAccessorUtil.ObtainConatiner > ().Resolve<ISessionFactory>(); > CurrentSessionContext.Bind(factory.OpenSession()); > } > > private void CloseSession(object sender, EventArgs e) > { > var factory = WindsorContainerAccessorUtil.ObtainConatiner > ().Resolve<ISessionFactory>(); > if (!CurrentSessionContext.HasBind(factory)) return; > > var session = CurrentSessionContext.Unbind(factory); > session.Dispose();; > }} > > and I register this module in web.config. then I need to manage my > transactions. I use Monorail as my web framework and create a filter > to manage this. > public class TransactionFilter : Filter > { > private readonly ISession session; > > public TransactionFilter(ISession session) > { > this.session = session; > } > > protected override bool OnBeforeAction(IEngineContext context, > IController controller, IControllerContext, controllerContext) > { > session.BeginTransaction(); > return base.OnBeforeTransaction(); > } > > protected override void OnAfterAction(IEngineContext context, > IController controller, IControllerContext, controllerContext) > { > using(session.Transaction) > { > if(context.LastException == null) > { > session.Transaction.Commit; > } > else > { > session.Transaction.Rollback(); > } > } > }} > > Each Controller/ViewComponent action then becomes it's own unit of > work. This drives the design of the workflow within each action. > I then register the TransactionFilter in the Kernel as transient and > place a FilterAttribute for the TransactionFilter on any controller > that requires is. If I don't need a transaction for a specific action > i can apply the SkipFilter attribute to that action. > > On Jan 25, 5:03 am, Sheri <[email protected]> wrote: > > > > > Hi! > > > How can I register the sessionfactory in IKernel? > > > API in the documentation is not enough for me. > > > I have a class as following: > > > ______________________________ > > using System.Web; > > using NHibernate; > > using NHibernate.Cfg; > > > namespace WebMonitorUpdate.SQLServerServices > > { > > public sealed class DBConnectionService > > { > > static readonly DBConnectionService instance = new > > DBConnectionService(); > > private const string CurrentSessionKey = "_session"; > > private static readonly ISessionFactory sessionFactory; > > > static DBConnectionService() > > { > > if(DBConnectionService.sessionFactory == null) > > sessionFactory = new Configuration().Configure > > ().BuildSessionFactory(); > > } > > > DBConnectionService() > > { > > } > > > public static DBConnectionService Instance > > { > > get > > { > > return instance; > > } > > } > > > public ISession OpenSession() > > { > > HttpContext context = HttpContext.Current; > > ISession currentSession = context.Items[CurrentSessionKey] > > as ISession; > > > if (currentSession == null) > > { > > currentSession = sessionFactory.OpenSession(); > > context.Items[CurrentSessionKey] = currentSession; > > } > > > return currentSession; > > } > > > public void CloseSession() > > { > > HttpContext context = HttpContext.Current; > > if (context == null) return; > > ISession currentSession = context.Items[CurrentSessionKey] > > as ISession; > > > if (currentSession == null) > > { > > // No current session > > return; > > } > > > currentSession.Close(); > > context.Items.Remove(CurrentSessionKey); > > } > > > public void CloseSessionFactory() > > { > > if (sessionFactory != null) > > { > > sessionFactory.Close(); > > } > > } > > }} > > > _________________________________ > > > And I will register this class in the IKernel. could I do this? how? > > if no, what do I missing here?! > > > Thanks in advance > > Sheri > > > On 21 Jan, 19:42, Jason Meckley <[email protected]> wrote: > > > > there are 2 configurations in this scenario. Nhibernate andCastle. > > > Nhibernate configuration is very easy to figure out using the xml > > > schema docs.Castle, on the other hand is very open ended. the > > > documentation (found > > > herehttp://www.castleproject.org/container/documentation/v21/index.html) > > > is the best place to start. because each facility/component can be > > > configured uniquely there is no xml schema. however the amount > > > ofCastlexml configure is greatly reduced with the fluent registration > > > API. > > > > On Jan 21, 10:33 am, Sheri <[email protected]> wrote: > > > > > Thanks for your answer Jason! > > > > > I am almost newbie and I need more details. like how to configure the > > > > configuration file (web.config) withcastle... > > > > > Hope somebody can help! > > > > > Regards > > > > Sheri > > > > > On 21 Jan, 15:21, Jason Meckley <[email protected]> wrote: > > > > > > the 2 frameworks solve unique problems. they can be used together, but > > > > > how that is done is really up to you. the common approach is to > > > > > register the configuration and session factory as singletons in the > > > > > container. then resolve the session from the factory by implementing > > > > > ISubDependencyResolver. to resolve the same session for a given scope > > > > > use the ISessionFactory.GetCurrentSession() method. > > > > > defining the session and transaction boundaries is up to you. for web > > > > > applications most use a Session per Request and implement a > > > > > Transaction Filter. > > > > > > You can also use IoC with NH by implementing your own BytecodeProvider > > > > > and ReflectionOptimizer. this isn't required, but can be helpful if > > > > > dependency injection is required. > > > > > > I believe there is a Nhibernate Facility as part of theCastlesource > > > > > code which handles most/all of the first paragraph above. Because I > > > > > use the trunk of both NH andCastleI have found it's easier to simply > > > > > roll my own facility for each project rather than manage all the > > > > > project dependencies each time I build from the trunk. > > > > > > On Jan 21, 7:34 am, Sheri <[email protected]> wrote: > > > > > > > Hello! > > > > > > > Does anyone know any god link/documentation to usingCastle(Kernel/ > > > > > > Facilities/Windsor) in NHibernate 2.1. > > > > > > > Thanks in advance > > > > > > /Sheri -- You received this message because you are subscribed to the Google Groups "nhusers" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/nhusers?hl=en.
