ActionOfWork in Action Filter似乎是缓存

Jer*_*ose 12 asp.net-mvc caching inversion-of-control unit-of-work action-filter

我有一个使用IoC(Unity)的MVC 3站点,我的模型是用EF4和POCO生成的.我正在使用动作过滤器来提交我的UnitOfWork:

public class UseUnitOfWorkAttribute : ActionFilterAttribute, IActionFilter
{
    private readonly IUnitOfWork _unitOfWork;

    public UseUnitOfWorkAttribute()
    {
        _unitOfWork = IoCFactory.Instance.CurrentContainer.Resolve<IUnitOfWork>();
    }

    void IActionFilter.OnActionExecuted(ActionExecutedContext filterContext)
    {
        _unitOfWork.Commit();
    }

    void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

然而,即使Commit()似乎被解雇了,它似乎在某种程度上缓存了它认为"肮脏"的东西.

例如,在我的控制器中,以下内容从服务类执行:

var user = _userRepository.Single(u => u.Id == 2);
user.DateAdded = DateTime.Now;
Run Code Online (Sandbox Code Playgroud)

每当我重新构建解决方案并点击此控制器操作时,实际上都会提交更改.但是,对控制器的连续命中不会做任何事情.

另一方面,如果我将UnitOfWork放在我的控制器中并在服务方法调用之后提交它,它会按预期工作(每次我请求控制器操作时):

public AccountController()
{
    _unitOfWork = IoCFactory.Instance.CurrentContainer.Resolve<IUnitOfWork>();
}

public ActionResult Test()
{
    var user = _userRepository.Single(u => u.Id == 2);
    user.DateAdded = DateTime.Now;
    _unitOfWork.Commit();
}
Run Code Online (Sandbox Code Playgroud)

所以看起来肯定会出现某种缓存,但我无法弄清楚缓存的内容 - UnitOfWork,ActionFilter或存储库.

什么想法可能会发生什么?如果没有,任何想法我还能做些什么来排除故障?

提前致谢.

Dar*_*rov 27

您正在操作过滤器的构造函数中初始化您的工作单元,这意味着它将在实例化操作过滤器时注入.引用ASP.NET MVC 3发行说明:

在以前版本的ASP.NET MVC中,除少数情况外,每个请求都创建了操作过滤器.这种行为从来都不是保证行为,而只是一个实现细节,而过滤器的合同是将它们视为无状态.在ASP.NET MVC 3中,过滤器被更积极地缓存.因此,任何不正确地存储实例状态的自定义操作过滤器都可能被破坏.


Tho*_*yde 6

确保依赖项容器在所有位置返回相同的实例,并重写过滤器以避免状态缓存:

public class UseUnitOfWorkAttribute : ActionFilterAttribute, IActionFilter
{
    void IActionFilter.OnActionExecuted(ActionExecutedContext filterContext)
    {
        var unitOfWork = IoCFactory.Instance.CurrentContainer.Resolve<IUnitOfWork>();
        unitOfWork.Commit();
    }

    void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)