Ste*_*ven 14 .net c# asp.net dependency-injection asp.net-web-api
在ASP.NET Web API(4.0.30506)中似乎有一些奇怪的行为,我以前没见过.
我所看到的是,相同的动作过滤器属性实例在Web API请求上重用.如果此属性将依赖项注入其中,这尤其是一个问题,因为这些依赖项可能特定于Web请求.我知道属性更好是被动的,但我的假设是动作过滤器属性没有被缓存.
我搜索了描述这个的任何文章,博客文章或微软更改日志及其背后的原因,但我找不到一件事.这让我想知道我的配置是否有问题导致这种情况发生.但是,我能够在一个新的,空的Visual Studio 2012 Web API项目中重现这个问题.
我所做的是使用带有"Web API"模板的Visual Studio 2012 ASP.NET MVC 4 Web应用程序项目创建一个新的空项目.它附带了Web API 4.0.20710.0 NuGet包.之后我添加了以下属性:
[DebuggerDisplay("{id}")]
public class TestFilterAttribute : System.Web.Http.Filters.ActionFilterAttribute {
private static readonly List<int> used = new List<int>();
private static int counter;
private readonly int id;
public TestFilterAttribute() {
this.id = Interlocked.Increment(ref counter);
}
public override void OnActionExecuting(HttpActionContext actionContext) {
// Just for testing: I would expect this line never to throw, but it does.
if (used.Contains(this.id)) throw new Exception("WAT?");
used.Add(this.id);
base.OnActionExecuting(actionContext);
}
}
Run Code Online (Sandbox Code Playgroud)
我将此属性添加到ValuesController(默认模板的一部分):
public class ValuesController : ApiController {
// GET api/values
[TestFilterAttribute]
public IEnumerable<string> Get() {
return new string[] { "value1", "value2" };
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
现在,当我启动项目时,转到浏览器中的/ api/values并刷新该页面几次,"WAT?" 抛出异常.
这是Web API的正常行为吗?如果是这样,这是什么原因?或者我在某处遗漏了一些有关此更改的备忘录?这是否使Web API属性更适合进行依赖注入?或者我做错了什么?
Mih*_*scu 18
Web API建立在MVC之上,因此它使用了很多功能.
属性实例可重用性是MVC 3引入的积极缓存的一部分.这意味着相同的Attribute实例最有可能与其应用的所有实例一起使用Actions.MVC管道将尽力将您的Attribute类视为一个Singleton.
因为重用了相同的Attribute 实例,所以不会调用它的构造函数,id也不会递增.例如,如果你id在里面增加OnActionExecuting,那么一切都会好起来的.
您仍然可以随心所欲地做任何事情Attribute.您只需要记住,不能保证始终可以创建新实例.该构造函数不应该包含什么,但最初的初始化.
public TestFilterAttribute() {
// Instance will be reused thus this will not be called for each Action
}
public override void OnActionExecuting(HttpActionContext actionContext) {
// Called on each Action
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3039 次 |
| 最近记录: |