Action Filter 中的 UnitOfWork 似乎正在缓存

发布于 2024-10-22 03:24:58 字数 1342 浏览 9 评论 0原文

我有一个使用 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)
    {
    }
}

但是,即使 Commit() 似乎被解雇了,但它似乎在缓存它认为“脏”的内容。

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

var user = _userRepository.Single(u => u.Id == 2);
user.DateAdded = DateTime.Now;

每当我重新构建解决方案并点击此控制器操作时,实际上都会提交更改。然而,连续点击控制器不会执行任何操作。

另一方面,如果我将一个 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();
}

所以看起来肯定正在进行某种缓存,但是我无法弄清楚缓存的是什么——UnitOfWork、ActionFilter 或存储库。

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

提前致谢。

I have an MVC 3 site that uses IoC (Unity), and my model is generated w/ EF4 and POCOs. I am using an action filter to commit my 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)
    {
    }
}

However, even though the Commit() seems to be getting fired, it somehow seems to be caching what it thinks is "dirty".

For example, in my controller, the following gets executed from a service class:

var user = _userRepository.Single(u => u.Id == 2);
user.DateAdded = DateTime.Now;

Whenever I do a fresh build of the solution and hit this controller action, the change is actually committed. However, successive hits to the controller doesn't do anything.

On the other hand, if I put a UnitOfWork in my controller and commit it following the service method call, it works as expected (every time I request the controller action):

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();
}

So it definitely seems like some sort of caching is going on, but I can't figure it out what is getting cached -- the UnitOfWork, the ActionFilter, or the repository.

Any ideas what could be going on? And if not, any ideas what else I could do to troubleshoot?

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

筱果果 2024-10-29 03:24:58

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

在 ASP.NET MVC 的早期版本中,
动作过滤器是根据
请求,但少数情况除外。这
行为从来都不是有保证的
行为而仅仅是一种实现
过滤器的详细信息和合同
是认为他们无国籍。在
ASP.NET MVC 3,过滤器缓存更多
积极地。因此,任何习惯
不正确存储的动作过滤器
实例状态可能会被破坏。

You are initializing your unit of work in the constructor of the action filter which means that it will be injected when the action filter is instantiated. Quote from the ASP.NET MVC 3 release notes:

In previous versions of ASP.NET MVC,
action filters were created per
request except in a few cases. This
behavior was never a guaranteed
behavior but merely an implementation
detail and the contract for filters
was to consider them stateless. In
ASP.NET MVC 3, filters are cached more
aggressively. Therefore, any custom
action filters which improperly store
instance state might be broken.

迷乱花海 2024-10-29 03:24:58

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

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

    void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
    {
    }
}

Make sure the dependency container returns the same instance in all places and rewrite the filter to avoid state caching:

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

    void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
    {
    }
}
岁月苍老的讽刺 2024-10-29 03:24:58

我会检查你的存储库的生命周期。这无疑是我们实施过程中的罪魁祸首。

I would check the lifetime on your repository. That was certainly the culprit in our implementation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文