3

我在 ASP.NET MVC 应用程序中将 Castle Windsor 与 NHIbernate 一起用于我的 IoC。它很好用,注册如下(有一个例外):

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”时检测到依赖周期。导致循环的解析树如下: 组件 'Late bound NHibernate.ISession' 解析为组件 'Blah.Core.Services.AccountSession' 的依赖项 解析为组件 'Blah.Core.Infrastructure.Data.ChangeAuditInfoInterceptor' 的依赖项解析为组件'Blah.Core.Infrastructure.Installers.SessionFactoryBuilder'的依赖关系解析为组件'后期绑定NHibernate.ISessionFactory'的依赖关系解析为组件'后期绑定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
    {
...
    }

...ETC。

4

1 回答 1

4

尝试在拦截器类中添加对 Func<ISession> 的依赖项

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;
    }));
于 2013-08-22T13:57:31.217 回答