below is some simple code:
[SimpleFilter]
public class MyController : ControllerBase
{
public MyController() {
<---------- I put a debugger here
}
[Route("")]
public string Get() {
return DateTime.Now.ToLongTimeString();
}
}
public class SimpleFilterAttribute : Attribute, IAsyncResourceFilter
{
public SimpleFilterAttribute() {
// <---------- I put a debugger here
}
public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next) {
...
}
}
So we know that when the appication is running, it will create a new controller instance to handle each request, so if I make 5 requests, then 5 MyController instance will be newed up, I can verify it by putting a debugger in MyController's constructor, every time the control goes to the debugger.
So I assume the same thing should happen to filter too, a new fiter instance will be created to handle every new request, but strange things happen as below:
1-When the application first starts, the SimpleFilter's constructor gets invoke twice, which means two instance of SimpleFilter newed up, so why application creates two instances of this fiter?
2-After the application is running, everytime I make a new request, no new SimpleFilter instance created, it looks like a single filter instance is used to handle all requests, is it true? If it is true, why we need a new controller instance for every request while only a single filter instance is needed for all requests?
Interesting question about two times called filter constructor.
It looks it is CLR specific behaviour not aspnet-core. Each time TypeInfo.GetCustomAttributes() is called, attribute instance is created.
You can check that yourself by calling
var typeInfo = typeof(MyController).GetTypeInfo();
var attribes = typeInfo.GetCustomAttributes();
And while constructing controller info TypeInfo.GetCustomAttributes() is called at least 2 times
https://github.com/dotnet/aspnetcore/blob/main/src/Mvc/Mvc.Core/src/ApplicationModels/DefaultApplicationModelProvider.cs#L110