Windsor的Scope缓存已经在Envers自定义修订监听器中处理

时间:2013-04-27 16:02:49

标签: castle-windsor nhibernate-envers

更新:我认为是 Windsor配置,有没有人知道我没有正确配置Windsor?

我目前在C#WebApi项目中使用Envers。 Windsor用于IoC。 我有一个自定义的RevisionEntity,它添加了一个User属性来审核已经改变数据的用户。

为确保所有配置都正确,我在这里开始使用"简单的字符串"在NewRevision方法中添加;

public class AuditRevisionListener : IRevisionListener
{
    public void NewRevision(object revisionEntity)
    {
        ((AuditRevision)revisionEntity).User = "Simple string here";
    }
}

并且所有这些都按预期持续存在。

下一步是实现我需要获取UserService的完整User对象;

public class AuditRevisionListener : IRevisionListener
{
    public void NewRevision(object revisionEntity)
    {
        var userServices = (IUserServices)GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IUserServices));
        var user = userServices.GetRequestingUser();

        ((AuditRevision)revisionEntity).User = user;
    }
}

然而,DependencyResolver.GetService抛出错误; " 无法访问已处置的对象。对象名称:'范围缓存已经处理完毕。这很可能是调用代码中的错误。'。 "

更新 我现在在https://github.com/ScottFindlater/WindsorEnversIssue

创建了一个演示项目

在首次设置解决方案时,所有内容都可以正常运行,因为自定义Envers RevisionListener 执行任何依赖项解析。

运行执行GET的解决方案到HomeController,它只加载一个用户并修改另一个用户;

  • 依赖性解析显示有效,因为有一个名为DependencyResolverDoesWork的ActionFilter可以成功解析UserServices。
  • Envers显示在填充UserAudit表时正常工作。

要“打开”客户版本的修订版解析器导航到;域NHibernate项目,审计文件夹,AuditRevisionListener类,NewRevision方法并取消注释2行代码。

完全重建然后再次运行解决方案,项目将在WindsorDependencyResolver类中运行时间异常,GetService方法带有“无法访问已处置对象”,并单击“查看详细信息操作”会展开此消息“{" 无法访问已处置的对象。\ r \ n对象名称:'范围缓存已经处理完毕。这很可能是调用代码中的错误。'。"}“。

Roger发布的评论,非常感谢你,这表明将LifeStyle改为Singleton确实有效。但是,此演示有目的地保持简单,并且需要使用PerWebRequest LifeStyle,因为实际项目中的ApplicationServices具有注入的上下文相关数据,例如请求用户以强制执行安全性。

我现在陷入困境,任何关于我设置错误的指针/答案都会感激不尽。另外,我知道这已发布在SO和Envers论坛上,我将更新两者的答案。

我认为是温莎配置,有没有人知道我没有正确配置温莎?

1 个答案:

答案 0 :(得分:2)

我没有尝试过运行您的示例,但我认为这取决于您的web.config中定义的两个http模块之间的相互作用(https://github.com/ScottFindlater/WindsorEnversIssue/blob/master/API%20Endpoints/Web.config

  • Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule - 控制“每个网络请求”组件的生命周期

  • APIEndpoints.HttpModules.NHibernateSessionCoordinator - 打开会话并在每个Web请求开始时开始一个事务,然后提交事务并在Web请求结束时处理会话

在您提交事务时 - 在请求结束时,由NHibernateSessionCoordinator触发,您对NHibernate ISession中的对象所做的任何更改实际上都会写入数据库。这是Envers完成其工作的重点,反过来,您尝试从Windsor容器中解析IUserService。抛出异常是因为IUserService以“每个Web请求”生活方式注册,并且Windsor将当前Web请求视为已完成,并已处置与请求关联的任何对象。

您是否尝试过逆转定义HttpModules的顺序,例如: PerWebRequestLifestyleModule之前的NHibernateSessionCoordinator?这将导致您的NHibernate事务在每个Web请求组件被释放之前提交。