David Archer
unread,Sep 10, 2009, 10:52:42 AM9/10/09Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
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