与Castle Windsor IoC for NHibernate ISession的循环依赖

时间:2013-08-19 15:47:10

标签: nhibernate castle-windsor isession

我在一个ASP.NET MVC应用程序中使用Castle Windsor作为我的IoC以及NHIbernate。它的工作原理如下(有一个例外):

container.Register(Component.For<ISessionFactoryBuilder.().ImplementedBy<SessionFactoryBuilder>().LifestyleSingleton());

// Register the NHibernate session factory as a singleton using custom SessionFactoryBuilder.BuildSessionFactory method.
container.Register(Component.For<ISessionFactory>().UsingFactoryMethod(k => k.Resolve<ISessionFactoryBuilder>().BuildSessionFactory("ApplicationServices")).LifestyleSingleton());

container.Register(Component.For<IInterceptor>().ImplementedBy<ChangeAuditInfoInterceptor>().LifestylePerWebRequest());
container.Register(Component.For<ISession>().UsingFactoryMethod(k => k.Resolve<ISessionFactory>()
            .OpenSession(container.Resolve<IInterceptor>())).LifestylePerWebRequest()); 

一切都很好,只是因为我的ChangeAuditInterceptor又注入了一个IAccountSession服务,而这个服务又注入了一个NHibernate ISession ......这会导致以下循环依赖性异常:

  

尝试解析组件时检测到依赖关系循环   '后期绑定NHibernate.ISession'。产生的决议树   循环如下:组件'后期绑定NHibernate.ISession'   解析为组件的依赖关系   'Blah.Core.Services.AccountSession'被解决为依赖   组件'Blah.Core.Infrastructure.Data.ChangeAuditInfoInterceptor'   解析为组件的依赖关系   'Blah.Core.Infrastructure.Installers.SessionFactoryBuilder'解决了   作为组件'后绑定NHibernate.ISessionFactory'的依赖   解析为组件'Late bound NHibernate.ISession'的依赖关系   这是要解决的根组件。

在过去的几年里,我经常使用NHibernateSessionManager来处理IInterceptor中的信息,而不会导致这种循环依赖问题(与使用Castle Windsor的UsingFactoryMethod功能的SessionFactoryBuilder的使用相反)。

有关如何解决此循环依赖关系的任何建议?没有开始通过其他方式破解AccountSession的ISession(即属性注入围绕问题并且因此而闻起来)。我已经将ISession注入转换为AccountSession服务的属性注入,它工作正常,但我不喜欢隐式契约与构造函数显式契约。

public class AccountSession : IAccountSession
{
    private readonly ISession _session;

    public AccountSession(ISession session)
    {
        _session = session;
    }

    public Account GetCurrentAccount() // Called by a method in ChangeAuditInterceptor
    {
...
    }

...等

1 个答案:

答案 0 :(得分:4)

尝试在Func&lt;上添加依赖项ISession&gt;在你的拦截器类

public class CustomInterceptor : EmptyInterceptor
{
    private readonly Func<ISession> sessionFunc;
    private ISession session;

    protected ISession Session
    {
        get
        {
            return session ?? (session = sessionFunc());
        }
    }

    public CustomInterceptor(Func<ISession> sessionFunc)
    {
        this.sessionFunc = sessionFunc;
    }
}

注册:

container.Register(Component.For<ISession>().
    LifestylePerWebRequest()
    .UsingFactoryMethod(container =>
    {
        var interceptor = container.Resolve<IInterceptor>();
        return container.Resolve<ISessionFactory>.OpenSession(interceptor);
    }));
container.Register(Component.For<Func<ISession>>()
    .LifestylePerWebRequest()
    .UsingFactoryMethod(container =>
    {
        Func<ISession> func = container.Resolve<ISession>;
        return func;
    }));