Castle Windsor、Fluent Nhibernate 和 Automapping Isession 关闭问题
Posted
技术标签:
【中文标题】Castle Windsor、Fluent Nhibernate 和 Automapping Isession 关闭问题【英文标题】:Castle Windsor, Fluent Nhibernate, and Automapping Isession closed problem 【发布时间】:2010-12-29 14:15:52 【问题描述】:我对整个温莎城堡、Nhibernate、Fluent 和 Automapping 堆栈都是新手,所以请原谅我的无知。我不想就此发布另一个问题,因为似乎已经有大量问题试图解决 Windsor nhib Isession 管理问题,但到目前为止,他们都没有解决我的问题。当我尝试从我的存储库调用 Db 时,我仍然收到 ISession is closed 异常,这是我的容器设置代码。
container.AddFacility<FactorySupportFacility>()
.Register(
Component.For<ISessionFactory>()
.LifeStyle.Singleton
.UsingFactoryMethod(() => Fluently.Configure()
.Database(
MsSqlConfiguration.MsSql2005.
ConnectionString(
c => c.Database("DbSchema").Server("Server").Username("UserName").Password("password")))
.Mappings
(
m =>
m.AutoMappings.Add
(
AutoMap.AssemblyOf<Message>(cfg)
.Override<Client>(map =>
map.HasManyToMany(x => x.SICCodes).Table("SICRefDataToClient");
)
.IgnoreBase<BaseEntity>()
.Conventions.Add(DefaultCascade.SaveUpdate())
.Conventions.Add(new StringColumnLengthConvention(),new EnumConvention())
.Conventions.Add(new EnumConvention())
.Conventions.Add(DefaultLazy.Never())
)
)
.ExposeConfiguration(ConfigureValidator)
.ExposeConfiguration(BuildDatabase)
.BuildSessionFactory() as SessionFactoryImpl),
Component.For<ISession>().LifeStyle.PerWebRequest.UsingFactoryMethod(kernel => kernel.Resolve<ISessionFactory>().OpenSession()
));
在我的存储库中,我注入 private readonly ISession session;
并按如下方式使用它
public User GetUser(int id)
User u;
u = session.Get<User>(id);
if (u != null && u.Id > 0)
NHibernateUtil.Initialize(u.UserDocuments);
return u;
在我的 web.config 里面 <httpModules>
。我也添加了这一行
<add name="PerRequestLifestyle"
type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor"/>
我在这里仍然遗漏了部分难题,我无法相信这是一个如此复杂的配置,以满足任何使用 nHibernate 和 Castle Windsor 开发 Web 应用程序的基本需求。
我一直在尝试遵循windsor-nhibernate-isession-mvc 此处的代码,并在那里发布了我的问题,因为他们似乎有完全相同的问题,但我的问题没有解决。
更新 MooKid8000 我现在已经将我的城堡注册码更新为这个
private void AddRepositories()
container.Register(
AllTypes.FromAssembly(typeof(MembershipRepository).Assembly)
.Pick()
.Configure(c => c.Interceptors(
InterceptorReference.ForKey("simpleLogger")).Anywhere
)
.Configure(c => c.LifeStyle.Is(LifestyleType.Transient))
.WithService.FirstInterface());
但是我仍然遇到 ISession 已关闭的问题,我的服务是否也需要注册为 Transient,您能否更详细地解释一下为什么它们应该是瞬态的而不是单例的
更新 MooKid8000 的建议是 100% 正确的,我只需要确保我的服务和存储库的范围都为 LifestyleType.Transient,这样 ISession 就不会被清除。很棒的地方 Mookid8000 最初甚至没有看到我的城堡注册码。
有兴趣的朋友可以联系我,我可以把我的容器设置发给你。
【问题讨论】:
您可能有兴趣阅读使用 ASP.NET MVC 和 NHibernate 的 Windsor 教程,该教程面向没有 Windsor 或 IoC 概念经验的人。 stw.castleproject.org/…如果有任何不清楚、令人困惑或解释不够清楚的地方,请不要忘记分享您对教程的反馈 流畅的语法是最糟糕的。我什至不会尝试阅读这些代码试图做什么。对不起。 我稍后会详细检查这个,当我在过去几周连续几个小时搜索这样一个 asp.net mvc 3 示例时,这是在哪里 Phil 是的,很难理解正在发生的事情,我一直在接受帮助,我收到了以这种方式设置项目的帮助,流畅的休眠代码运行良好,尽管看起来很脏,问题是我的 ISession不是根据请求创建并注入到存储库中,它总是关闭 【参考方案1】:您是否记得以短暂的生活方式注册您的存储库?
如果您的存储库是单例的(这是 Windsor 的默认生活方式),则注入的 ISession
实例将被“捕获”,从而导致稍后关闭会话错误。
请注意,使用您的存储库的任何服务也必须具有短暂的生活方式,以及使用这些服务的任何服务等等。
通常,您可以说生活方式粒度不应随着您远离组合根而增加,否则会发生某种范围界定。当然,这并不总是一个问题,但它可能会导致难以诊断的错误。
【讨论】:
我已经更新了我的主要问题,所以我可以添加更多代码,但是当我尝试访问数据库时,我仍然收到 ISession 已关闭 好的 - 但是依赖于您的存储库的任何服务怎么样?我的怀疑是每个请求范围为ISession
被意外地限定为单例,这通常会导致您遇到错误。
mookid 已修复 我现在将所有服务的范围设置为 LifestyleType.Transient 并且当我访问存储库时 ISession 是活动的,我现在可以重新打开延迟加载 ;-),非常感谢我知道它必须是一些简单的东西,但是当你对所有东西都不熟悉时,你很难发现它。我真的需要在城堡上做更多的阅读,非常感谢,我已经为此撕毁了 3 周的头发。以上是关于Castle Windsor、Fluent Nhibernate 和 Automapping Isession 关闭问题的主要内容,如果未能解决你的问题,请参考以下文章
如何访问 Castle Windsor 的 Fluent Interfaces API?
Castle.Windsor依赖注入的高级应用_Castle.Windsor.3.1.0