我在ASP.NET MVC应用程序中使用Castle Windsor作为我的IoC和NHIbernate。它的伟大工程注册(有一个例外)如下:与Castle Windsor IoC for NHibernate的循环依赖关系ISession
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的注入......这导致了下列好循环依赖异常:
尝试解析组件 'Late bound 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 plunking而不引起这个循环依赖问题(相对于这种用法,它使用温莎城堡的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
{
...
}
...等等。
我想你应该给一个尝试转变_session到一个公共的自动属性(get; set;)并删除AccountSession的构造函数(因此留给编译器自动生成的无参数公共构造函数)。值得一试(恕我直言) – jbl
这就是我所做的,它工作得很好。但是,我不喜欢需要隐式契约与显式契约,特别是在其他地方使用它(尽管DI都由容器处理,因此您不必考虑它)。它闻起来是因为这是一个周期性的参考,我觉得我错过了一些东西(尽管不像典型的循环参考那样脏)。 – Ted
哦,并感谢您对此和上一期的反馈。这听起来像你和我一样对好的/最好的解决方案有同样的好奇心。我之前已经尝试了Castle NHibernate Facility,但它需要[Transaction]标记来刷新和注入工厂等。也许答案是要返回NHibernate会话管理器,它将被注入到处(而且可以处理IInterceptor注射本身)。多年来,我使用Ninject,最近更换了Castle和Autofac。 – Ted