如何从全局过滤器中的 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 缓存不会清晰并使用上述功能进行更新,有什么建议吗?请帮忙..
在这里看到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 过滤器将有权访问最新的安全数据