在 Web 应用程序中何处以及如何使用拦截器?

2024-04-24

我最近对拦截器概念很感兴趣。我知道这个概念在 NHibernate、Entity Framework 等许多库中都有使用。但我对如何在 ASP.NET MVC Web 应用程序中使用这个概念感兴趣。

在 Mvc Web 应用程序中什么地方有用?

有没有使用拦截器的开源 Asp.Net Mvc 项目?

Asp.net Mvc 已经支持一种带有过滤器的控制器拦截器。使用过滤器而不是拦截器更好?


何时/何地使用拦截器

查看您以前开发的应用程序并检查代码。查找在方法和属性的开头或结尾处经常重复的代码。您可以考虑将这段代码从所有这些方法移至拦截器中。例如,我注意到许多执行输入验证的 MVC 操作都是使用相同的几行代码来实现的:

if (!ModelState.IsValid)
    return View(model);

这些代码可能会被移动到拦截器(在本例中可能是 MVC 过滤器)。编写和应用过滤器的成本是否超过了重复代码的成本? (2 行代码乘以使用此代码的控制器操作数)。在这种情况下,也许不是。然而,在其他情况下,使用拦截器的好处会更大。

以下是我认为可能发生此类代码重复的一些情况的列表,即场景smell就像他们可以从拦截器中受益:

  • 输入验证(如上图所示)。
  • 调试日志。你可以写一个拦截器 http://ayende.com/blog/3474/logging-the-aop-way记录每个方法调用的进入和退出。
  • 线程同步。您的问题是关于 Web 应用程序的,但如果您正在开发具有 MVP 样式视图的 Windows 应用程序,您可以应用一个拦截器来确保所有方法调用都同步回 UI 线程。
  • 数据库事务。我的大部分数据库事务代码如下所示:

 

using (var transaction = Session.BeginTransaction())
{
    // ... do some work that is unique to this method ...
    transaction.Commit();
}
  • PropertyChanged 事件实现。这段代码通常非常重复并且写起来很烦人。Sacha Barber 深入探索了如何使用各种框架自动实现此事件 http://www.codeproject.com/Articles/140042/Aspect-Examples-INotifyPropertyChanged-via-Aspects.
  • 安全。您的应用程序中可能有许多方法应仅限于某些用户。The AuthorizeAttribute http://msdn.microsoft.com/en-us/library/system.web.mvc.authorizeattribute.aspx正是针对这一点的过滤器。
  • Web 服务请求限制。某些 API,例如 Basecamp 的 API,要求您限制你的要求 https://github.com/37signals/bcx-api#rate-limiting每个给定时间范围内一定数量的请求。如果您编写了 Basecamp 客户端类,则可以对其应用拦截器,以确保所有方法调用都遵守速度限制,使用Thread.Sleep必要时。
  • 结果缓存。 MVC 有一些为此目的预先构建的过滤器 http://msdn.microsoft.com/en-us/library/system.web.mvc.outputcacheattribute.aspx。您可以编写自己的拦截器来缓存 UI 层下面的层的结果。
  • WCF 错误处理。你不能Dispose一个 WCF 客户端,如果它位于Faultedstate,因此每个创建和销毁客户端实例的方法都需要检查状态,然后调用Abort如果有必要,而不是简单地包装using围绕客户的条款。在这种情况下,拦截器可能不是最合适的。这可能更容易只是修复Dispose实现或使用某种包装器 http://coding.abel.nu/2012/02/using-and-disposing-of-wcf-clients/.

上述示例是否适合拦截器取决于您的应用程序的独特复杂性。当然,这个清单并不详尽,也不可能详尽。拦截器的可能应用程序与您编写的应用程序一样多种多样。

如何使用拦截器

我可以想到您可能希望应用拦截器的三个主要位置:控制器、服务和域对象。

  • With an MVC控制器,继续使用是最有意义的MVC 的过滤器 http://msdn.microsoft.com/en-us/library/gg416513%28v=vs.98%29.aspx.
  • For a 中间层服务您将从 IoC 容器中取出的过滤器不是一个选项(因为它不是控制器),因此您应该使用IoC 容器的拦截功能 https://github.com/castleproject/Windsor/blob/master/docs/interceptors.md.
  • 为您领域对象您通常要么直接使用构造函数实例化(如果它是一个新实体),要么从您选择的 ORM 中获取(如果它是现有实体),您需要使用某种对象工厂而不是构造函数和指导您的 ORM 如何使用工厂 http://nhibernate.info/blog/2008/12/12/entities-behavior-injection.html.

有关如何完成所有这些的具体细节取决于您使用的工具。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Web 应用程序中何处以及如何使用拦截器? 的相关文章

随机推荐