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.

Reply via email to