本文介绍了NHibernate ISession 与 Castle Windsor IoC 的循环依赖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 ASP.NET MVC 应用程序中使用 Castle Windsor 作为 IoC 和 NHIbernate.注册后效果很好(有一个例外):

I am using Castle Windsor for my IoC along with NHIbernate in an ASP.NET MVC app. It works great registered as follows (with one exception):

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 服务,而 IAccountSession 服务又注入了 NHibernate ISession...这导致了以下循环依赖异常:

All is good except that for my ChangeAuditInterceptor in turn has an IAccountSession service injected which in turn has an NHibernate ISession injected...which leads to the following circular dependency exception:

尝试解析组件时检测到依赖循环'后期绑定 NHibernate.ISession'.导致的分辨率树循环如下:组件'后期绑定NHibernate.ISession'解析为组件的依赖项'Blah.Core.Services.AccountSession' 解析为依赖组件'Blah.Core.Infrastructure.Data.ChangeAuditInfoInterceptor'解析为组件的依赖项'Blah.Core.Infrastructure.Installers.SessionFactoryBuilder' 已解决作为组件后期绑定 NHibernate.ISessionFactory"的依赖项解析为组件后期绑定 NHibernate.ISession"的依赖项这是正在解析的根组件.

在过去的几年里,我通常使用 NHibernateSessionManager 运行,它负责处理 IInterceptor 中的 plunking 而不会导致这种循环依赖问题(与使用 Castle Windsor 的 UsingFactoryMethod 功能的 SessionFactoryBuilder 的这种用法相反).

For the past couple years I've usually run with an NHibernateSessionManager which took care of plunking in the IInterceptor without causing this circular dependency issue (as opposed to this usage of a SessionFactoryBuilder which uses Castle Windsor's UsingFactoryMethod functionality).

关于如何解决这种循环依赖的任何建议?没有开始通过其他方式(即绕过问题并因此产生气味的财产注入)入侵 AccountSession 的 ISession.我已经将 AccountSession 服务的 ISession 注入切换为属性注入,它工作正常,但我不喜欢隐式契约与构造函数显式契约.

Any suggestions for how to resolve this circular dependency? Short of starting to hack in the ISession for the AccountSession via some other means (i.e. property injection which skirts around the issue and smells as a result). I've switched the ISession injection to property injection for the AccountSession service and it works fine, but I don't like the implicit contract vs. the constructor explicit contract.

public class AccountSession : IAccountSession
{
    private readonly ISession _session;

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

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

...等等

推荐答案

尝试添加对 Func 的依赖 在你的拦截器类中

Try to add a dependency on Func< ISession > in your interceptor class

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;
    }));

这篇关于NHibernate ISession 与 Castle Windsor IoC 的循环依赖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-02 06:04