Simple patch for WebSessionStorage

72 views
Skip to first unread message

David Archer

unread,
Sep 10, 2009, 10:52:42 AM9/10/09
to S#arp Architecture
Hello everyone,

I recently undertook integrating the latest Rhino.Security bits into
my project and there were a few pain points:

1) Rhino.Security wants to be able to pull the current ISession using
the ServiceLocator but this isn't supported out of the box by Sharp. I
ended up adding it to Windsor in the ComponentRegistrar.cs class in
the MyProject.Web project using something like this:

private static void AddRhinoSecurityComponentsTo
(IWindsorContainer container)
{
container.Kernel.Register(
// All the other stuff that Rhino Security needs
registered in the container
Component.For<ISession>()
.UsingFactoryMethod(() =>
NHibernateSession.Current)
.LifeStyle.Is(LifestyleType.Transient)
);
}

The trouble I ran into initially is that the WebSessionStorage and
Windsor are both out-of-the-box trying to Dispose/Close the ISession
at the end of the request. This ended up giving me an exception
"Session is already closed" since Windsor would Dispose/Close the
ISession and then the WebSessionStorage would try to do the same. The
fix was to create a custom WebSessionStorage that only closes the
session if it is open:

private void Application_EndRequest(object sender, EventArgs
e)
{
ISession session = Session;

if (session != null)
{
// The only changed line is below this comment :)
if (session.IsOpen) session.Close();
HttpContext context = HttpContext.Current;
context.Items.Remove(factoryKey);
}
}

This works and resolves the issue. Anyone see any gotchas here or
reasons this can't be integrated into trunk?

2) Rhino Security needs access to the NHibernate Configuration object
after it is created but before the Session Factory is built. Luckily,
there is a way to do this but I'm not sure that this is the right way.
I saw that the NHibernateSession.Init() function has an overload that
takes in a FluentNHibernate.Cfg.Db.IPersistenceConfigurer and that
object gets passed the NHibernate configuration at the correct time
during the initialization process. I ended up creating a
RhinoSecurityPersistenceConfigurer class like so:

using MyProject.Core;
using FluentNHibernate.Cfg.Db;
using NHibernate.Cfg;
using Rhino.Security;

namespace MyProject.Web.CastleWindsor
{
public class RhinoSecurityPersistenceConfigurer :
IPersistenceConfigurer
{
public Configuration ConfigureProperties(Configuration
nhibernateConfig)
{
Security.Configure<User>(nhibernateConfig,
SecurityTableStructure.Prefix);

return nhibernateConfig;
}
}
}


and I changed the call to NHIbernate.Init() in global.asax.cs to:

var config = NHibernateSession.Init(
webSessionStorage,
new[] { Server.MapPath("~/bin/MyProject.Data.dll") },
new AutoPersistenceModelGenerator().Generate(),
Server.MapPath("~/NHibernate.config"),
null, null, new RhinoSecurityPersistenceConfigurer());

I'm really not sure if this is the "right way" to do this but there
didn't seem to be any other facility in Sharp to be able to access the
NHibernate Configuration object prior to the Session Factory being
created. Technically, it _is_ "configuring the persistence" for Rhino
Security (setting up object mappings and tables and such) so I don't
think it's too much of a hack.

Hope this helps anyone trying to get the latest Rhino.Security working
with Sharp. Please let me know if you see any issues in getting the
change from #1 rolled into trunk.

Thanks,

David Archer

Billy

unread,
Sep 14, 2009, 5:41:20 PM9/14/09
to S#arp Architecture
Thanks for posting this David! I'll be sure to include a link to this
message in a previous blog post I wrote about integrating with Rhino
Security (until I muster some time to update the blog post directions
themselves ;).

Thanks again!

Billy McCafferty
Reply all
Reply to author
Forward
0 new messages