1

更新:我认为归结为温莎配置,有人知道我没有正确配置温莎吗?

我目前在 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没有执行任何依赖解析。

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

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

在客户 RevisionListener 导航到“打开”依赖解析;域 NHibernate 项目、审核文件夹、AuditRevisionListener 类、NewRevision 方法并取消注释 2 行代码。

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

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

我现在很困惑,任何关于我设置错误的指示/答案都将不胜感激。此外,我知道这已在 SO 和 Envers 论坛上发布,我将更新两者的答案。

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

4

1 回答 1

2

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

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

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

正是在您提交事务时——在请求结束时,由 NHibernateSessionCoordinator 触发,您对 NHibernate ISession 中的对象所做的任何更改实际上都会写入数据库。这是 Envers 做它的事情的地方,反过来,你尝试从 Windsor 容器中解析 IUserService。抛出异常是因为 IUserService 注册了“每个 Web 请求”生活方式,并且 Windsor 将当前 Web 请求视为完整,并已处理与该请求相关的所有对象。

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

于 2013-05-04T20:36:27.860 回答