如何从全局过滤器中的 NHibernate 会话获取更新的对象

本文关键字:NHibernate 会话 更新 对象 获取 全局 过滤器 | 更新日期: 2023-09-27 18:31:31

>我有以下全局过滤器代码:

public class UserAuthorizationFilter : FilterAttribute, IAuthorizationFilter
{
    private readonly IAdministratorService _administratorService;
    public UserAuthorizationFilter()
    {
        _administratorService = IoCFactory.Container.GetInstance<IAdministratorService>();
    }
    public void OnAuthorization(AuthorizationContext filterContext)
    {
        string username = HttpContext.Current.User.Identity.Name;
        IRequestMessage<string> request = MessageFactory.BuildRequestFor(username, username);
        Administrator administrator = _administratorService.GetDetailByName(request).Data;
        filterContext.Controller.ViewBag.Username = username;
        filterContext.Controller.ViewBag.IsAdmin = administrator != null;
        if (administrator != null)
        {
            bool isManageRole = administrator.Roles.Any(r => r.IsManageRole);
            bool isManageAdministrator = administrator.Roles.Any(r => r.IsManageAdministrator);
            bool isManageReviewer = administrator.Roles.Any(r => r.IsManageReviewer);
            filterContext.Controller.ViewBag.IsManageRole = isManageRole;
            filterContext.Controller.ViewBag.IsManageAdministrator = isManageAdministrator;
            filterContext.Controller.ViewBag.IsManageReviewer = isManageReviewer;
        }
    }
}

我在 global.asax 的Application_Start事件中添加了这个过滤器:

GlobalFilters.Filters.Add(new UserAuthorizationFilter(), 0);

当我将管理员角色属性(例如IsManageRole)从true更新到false时,数据已成功更新到数据库。然而UserAuthorizationFilter管理员对象中的属性角色没有更新,它仍然加载true值。 我试过打电话给sessionFactory.Evict(typeof(Role))session.Clear()但没有找到运气。数据仍然不会加载新更新的角色属性。如果我重新启动 Web 应用程序,属性已更新。

我该如何解决这个问题?为什么 nhibernate 缓存不会清晰并使用上述功能进行更新,有什么建议吗?请帮忙..

如何从全局过滤器中的 NHibernate 会话获取更新的对象

在这里看到IAdministratorService的实现会很有趣,它如何缓存.GetDetailByName(request)方法调用的结果。

关键是:ASP.NET MVC过滤器可以被视为单例。请参阅:是否跨线程重用 ActionFilterAttributes?这是如何工作的?

。在 MVC 3 ASP.NET 中,筛选器的缓存更加激进。因此,任何不正确地存储实例状态的自定义操作筛选器都可能被破坏...

让我们考虑一下它们,它们被实例化一次,它们永远存在而无需"重建"。 即没有通过构造函数的新 IoC/DI。

可能有更多的方法可以解决这个问题。

I.肮脏的方式是在每个OnAuthorization()中都打电话IoCFactory.Container.GetInstance<IAdministratorService>();。这很可能会返回新的新服务,并可以访问当前会话中的新数据。它应该在工作...但是:服务定位器是马克·西曼的反模式

II. 请参阅 Brad Wilson 关于在 MVC 中提供过滤器的文章,主要是:向过滤器添加依赖注入部分。简而言之,每个属性都使用Unity IoC通过二传手注入进行丰富。请参阅筛选器提供程序的代码段:

var attributes = base.GetActionAttributes(controllerContext,
                                              actionDescriptor);
foreach (var attribute in attributes) {
  _container.BuildUp(attribute.GetType(), attribute);
}

III. 我会使用一些由提供程序模式表示的共享"应用程序缓存"。(尽管提供者不是马克·西曼的模式)。

  • 过滤器将与某些SecurityManager通信。
  • 将有一些单例SecurityProvider,从当前会话中获取新数据并缓存它们。
  • 缓存将在一段合理的时间后被清理(我会说几分钟的安全)
  • "安全"对象上的事件系统也将触发cache.Clear()
  • AOP Mvc 过滤器将有权访问最新的安全数据