rhino.security and rhino.commons: circular dependency on ISession

11 views
Skip to first unread message

ChrisR

unread,
Nov 24, 2009, 1:20:33 PM11/24/09
to Rhino Tools Dev
When using the latest version of rhino.commons, how can the ISession
interface be provided for use with rhino.security?

If I attempt to register ISession using a factory method as below:

container.Register(
Component.For<ISession>()
.UsingFactoryMethod(() => UnitOfWork.CurrentSession)
.LifeStyle.Transient);

then I get a CircularDependencyException:

Castle.MicroKernel.Exceptions.CircularDependencyException: A cycle was
detected when trying to resolve a dependency. The dependency graph
that resulted in a cycle is:
- Service dependency 'CurrentSession' type 'NHibernate.ISession' for
NHibernate.ISession CurrentSession in type
Rhino.Commons.NHibernateUnitOfWorkFactory
+ Service dependency 'CurrentSession' type 'NHibernate.ISession' for
NHibernate.ISession CurrentSession in
Rhino.Commons.NHibernateUnitOfWorkFactory

Ayende Rahien

unread,
Nov 25, 2009, 3:40:49 AM11/25/09
to rhino-t...@googlegroups.com
I think that you need to register the factory facility


--

You received this message because you are subscribed to the Google Groups "Rhino Tools Dev" group.
To post to this group, send email to rhino-t...@googlegroups.com.
To unsubscribe from this group, send email to rhino-tools-d...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/rhino-tools-dev?hl=en.



ChrisR

unread,
Nov 25, 2009, 5:50:06 AM11/25/09
to Rhino Tools Dev
The factory facility is registered. Here is the complete container
initialisation code:

container.AddFacility<StartableFacility>();
container.AddFacility<FactorySupportFacility>();
container.AddFacility("logging.facility", new LoggingFacility
(LoggerImplementation.Log4net, "log4net.config"));

container.Register(
Component.For<INHibernateInitializationAware>()
.ImplementedBy<NHibernateMsSql2005ExpressInitialization>()
.LifeStyle.Singleton);
container.Register(
Component.For(typeof (IRepository<>))
.ImplementedBy(typeof (NHRepository<>))
.LifeStyle.Transient);
container.Register(
Component.For<IUnitOfWorkFactory>()
.ImplementedBy<NHibernateUnitOfWorkFactory>()
.LifeStyle.Singleton);

container.Register(
Component.For<IAuthorizationService>()
.ImplementedBy<AuthorizationService>()
.LifeStyle.Transient);
container.Register(
Component.For<IAuthorizationRepository>()
.ImplementedBy<AuthorizationRepository>()
.LifeStyle.Transient);
container.Register(
Component.For<IPermissionsBuilderService>()
.ImplementedBy<PermissionsBuilderService>()
.LifeStyle.Transient);
container.Register(
Component.For<IPermissionsService>()
.ImplementedBy<PermissionsService>()
.LifeStyle.Transient);

container.Register(
Component.For<ISession>()
.UsingFactoryMethod(() => UnitOfWork.CurrentSession)
.LifeStyle.Transient);


On 25 Nov, 08:40, Ayende Rahien <aye...@ayende.com> wrote:
> I think that you need to register the factory facility
>
> On Tue, Nov 24, 2009 at 8:20 PM, ChrisR <chrisrichards2...@gmail.com> wrote:
> > When using the latest version of rhino.commons, how can the ISession
> > interface be provided for use with rhino.security?
>
> > If I attempt to register ISession using a factory method as below:
>
> >      container.Register(
> >        Component.For<ISession>()
> >          .UsingFactoryMethod(() => UnitOfWork.CurrentSession)
> >          .LifeStyle.Transient);
>
> > then I get a CircularDependencyException:
>
> > Castle.MicroKernel.Exceptions.CircularDependencyException: A cycle was
> > detected when trying to resolve a dependency. The dependency graph
> > that resulted in a cycle is:
> >  - Service dependency 'CurrentSession' type 'NHibernate.ISession' for
> > NHibernate.ISession CurrentSession in type
> > Rhino.Commons.NHibernateUnitOfWorkFactory
> >  + Service dependency 'CurrentSession' type 'NHibernate.ISession' for
> > NHibernate.ISession CurrentSession in
> > Rhino.Commons.NHibernateUnitOfWorkFactory
>
> > --
>
> > You received this message because you are subscribed to the Google Groups
> > "Rhino Tools Dev" group.
> > To post to this group, send email to rhino-t...@googlegroups.com.
> > To unsubscribe from this group, send email to
> > rhino-tools-d...@googlegroups.com<rhino-tools-dev%2Bunsu...@googlegroups.com>
> > .

Ayende Rahien

unread,
Nov 25, 2009, 5:59:10 AM11/25/09
to rhino-t...@googlegroups.com
Hm, I don't think this is related to Rhino Security.
What is happening is that during the resolution of IUoWFactory, you are trying to access UnitOfWork.
That is likely going to cause issues.


To unsubscribe from this group, send email to rhino-tools-d...@googlegroups.com.

Ayende Rahien

unread,
Nov 25, 2009, 5:59:55 AM11/25/09
to rhino-t...@googlegroups.com
IOW,
The problem is that
NHibernateUnitOfWorkFactory.CurrentSession is settable.

ChrisR

unread,
Nov 25, 2009, 6:04:02 AM11/25/09
to Rhino Tools Dev
With the recent changes to Rhino.Security it now requires ISession to
be provided by the container, so how should I register ISession when
I'm using Rhino.Commons?

On 25 Nov, 10:59, Ayende Rahien <aye...@ayende.com> wrote:
> IOW,
> The problem is that
> NHibernateUnitOfWorkFactory.CurrentSession is settable.
>
> On Wed, Nov 25, 2009 at 12:59 PM, Ayende Rahien <aye...@ayende.com> wrote:
> > Hm, I don't think this is related to Rhino Security.
> > What is happening is that during the resolution of IUoWFactory, you are
> > trying to access UnitOfWork.
> > That is likely going to cause issues.
>
> >> <rhino-tools-dev%2Bunsu...@googlegroups.com<rhino-tools-dev%252Buns...@googlegroups.com>

Ayende Rahien

unread,
Nov 25, 2009, 6:18:50 AM11/25/09
to rhino-t...@googlegroups.com
Go to that property and add the attribute [DoNoWire] to it.

To unsubscribe from this group, send email to rhino-tools-d...@googlegroups.com.

Jason Meckley

unread,
Nov 25, 2009, 9:08:20 AM11/25/09
to Rhino Tools Dev
chris, you can also configure NH to use CurrentSessionContext and
resolve the session using a factory method
.AddFacilty<FactorySupportFacility>()
.Register(Component
.For<ISession>())
.UsingFactoryMethod(k=>k.Resolve<ISessionFactory>
().GetCurrentSession())
.LifeStyle.Is(LifeStyleType.Transient));

here is a link for configuring Current Session Context.
http://nhforge.org/wikis/howtonh/currentsessioncontext-for-desktop-development.aspx

note; if you have multiple session factories in your project, you
cannot use the FactoryMethod approach.
You need to implement SubDependencyResolver instead.

On Nov 25, 6:18 am, Ayende Rahien <aye...@ayende.com> wrote:
> Go to that property and add the attribute [DoNoWire] to it.
>
> > > >> <rhino-tools-dev%2Bunsu...@googlegroups.com<rhino-tools-dev%252Buns...@googlegroups.com>
> > <rhino-tools-dev%252Buns...@googlegroups.com<rhino-tools-dev%25252Bun...@googlegroups.com>

Tom Allard

unread,
Nov 26, 2009, 5:41:49 AM11/26/09
to Rhino Tools Dev
There is some other related issue i encountered and i thought I'd
share.

When you use transient components in combination with castle and one
your transient component has a dependency on a component that is
IDisposable, you should make sure to call IKernel.ReleaseComponent().
If you don't, you will be leaking memory in the form of
Castle.MicroKernel.Burden objects (the componet burden tracking
subsystem ).

Now ISession does extend IDisposable, hence this leak actually happens
when you are using this factory method.

Now you don't want MicroKernel to be calling Dispose on your ISession
either, since you are managing the ISession using Rhino.Commons, and
its the responsibility of NHibernateUnitOfWorkFactory to Disponse the
session.

I eventually solved the problem by plugging in my own
ComponentModelBuilder into MicroKernel, which in turn uses a custom
LifecycleModelInspector (LifecycleModelInspectorThatIgnoresISession)
that does not add a Decommission LifecycleStepType for ISession. (And
hence disables the burden tracking for ISession)

public class LifecycleModelInspectorThatIgnoresISession :
LifecycleModelInspector
{

public override void ProcessModel(IKernel kernel,
Castle.Core.ComponentModel model)
{
if (model == null)
{
throw new ArgumentNullException("model");
}
if (typeof(IInitializable).IsAssignableFrom
(model.Implementation))
{
model.LifecycleSteps.Add
(LifecycleStepType.Commission, InitializationConcern.Instance);
}
if (typeof(ISupportInitialize).IsAssignableFrom
(model.Implementation))
{
model.LifecycleSteps.Add
(LifecycleStepType.Commission, SupportInitializeConcern.Instance);
}
if (typeof(IDisposable).IsAssignableFrom
(model.Implementation)
&& !typeof(ISession).IsAssignableFrom
(model.Implementation)) //Session specific
{
model.LifecycleSteps.Add
(LifecycleStepType.Decommission, DisposalConcern.Instance);
}

}
}
}

There may be more elegant ways though...


-Tom
On Nov 25, 3:08 pm, Jason Meckley <jasonmeck...@gmail.com> wrote:
> chris, you can also configure NH to use CurrentSessionContext and
> resolve the session using a factory method
> .AddFacilty<FactorySupportFacility>()
> .Register(Component
>          .For<ISession>())
>          .UsingFactoryMethod(k=>k.Resolve<ISessionFactory>
> ().GetCurrentSession())
>          .LifeStyle.Is(LifeStyleType.Transient));
>
> here is a link for configuring Current Session Context.http://nhforge.org/wikis/howtonh/currentsessioncontext-for-desktop-de...
> > > > >> > > rhino-tools-d...@googlegroups.com<rhino-tools-dev%2Bunsubscribe@­googlegroups.com>
> > > <rhino-tools-dev%2Bunsu...@googlegroups.com<rhino-tools-dev%252Bunsubsc­ri...@googlegroups.com>
>
> > > > >> <rhino-tools-dev%2Bunsu...@googlegroups.com<rhino-tools-dev%252Bunsubsc­ri...@googlegroups.com>
> > > <rhino-tools-dev%252Buns...@googlegroups.com<rhino-tools-dev%25252Buns­ubsc...@googlegroups.com>
>
> > > > >> > > .
> > > > >> > > For more options, visit this group at
> > > > >> > >http://groups.google.com/group/rhino-tools-dev?hl=en.
>
> > > > >> --
>
> > > > >> You received this message because you are subscribed to the Google
> > > Groups
> > > > >> "Rhino Tools Dev" group.
> > > > >> To post to this group, send email to rhino-t...@googlegroups.com
> > > .
> > > > >> To unsubscribe from this group, send email to
> > > > >> rhino-tools-d...@googlegroups.com<rhino-tools-dev%2Bunsubscribe@­googlegroups.com>
> > > <rhino-tools-dev%2Bunsu...@googlegroups.com<rhino-tools-dev%252Bunsubsc­ri...@googlegroups.com>
>
> > > > >> .
> > > > >> For more options, visit this group at
> > > > >>http://groups.google.com/group/rhino-tools-dev?hl=en.
>
> > > --
>
> > > You received this message because you are subscribed to the Google Groups
> > > "Rhino Tools Dev" group.
> > > To post to this group, send email to rhino-t...@googlegroups.com.
> > > To unsubscribe from this group, send email to
> > > rhino-tools-d...@googlegroups.com<rhino-tools-dev%2Bunsubscribe@­googlegroups.com>
> > > .
> > > For more options, visit this group at
> > >http://groups.google.com/group/rhino-tools-dev?hl=en.- Hide quoted text -
>
> - Show quoted text -

Jason Meckley

unread,
Dec 1, 2009, 11:31:24 AM12/1/09
to Rhino Tools Dev
Tom, if all you want is to avoid the Kernel's model processing against
ISession. the logic could be simplified.
public class LifecycleModelInspectorThatIgnoresISession :
LifecycleModelInspector
{
public override void ProcessModel(IKernel kernel,
ComponentModel model)
{
if (typeof (ISession) == model.Implementation) return;
base.ProcessModel(kernel, model);
> > > >http://groups.google.com/group/rhino-tools-dev?hl=en.-Hide quoted text -

Tom Allard

unread,
Dec 2, 2009, 3:44:42 AM12/2/09
to Rhino Tools Dev
Right! Thank you!
> ...
>
> read more »- Hide quoted text -
Reply all
Reply to author
Forward
0 new messages