Given I have access only to ControllerContext
and not Action____Contexts
what is the optimal way to get the current executing ActionDescriptor?
So far the only method I've found is:
new ReflectedControllerDescriptor(context.Controller.GetType())
.FindAction(context, context.RouteData.GetRequiredString("action"));
Is this the optimal method?
The fact that class is named ReflectedControllerDescriptor
leads me to wonder if there is a heavy cost to this operation as it will be executed on every page request? Related to that is does this class internally cache or should I actually be caching ReflectedControllerDescriptors
explicitly?
You could try the ActionDescriptorof the ActionExecutingContextas follows: protected override void OnActionExecuting(ActionExecutingContext filterContext) { string actionName = filterContext.ActionDescriptor.ActionName; string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName .....
As you can see, the IControllerActivator.Create method is passed a ControllerContext which defines the controller to be created. How the controller is created depends on the particular implementation. Out of the box, ASP.NET Core uses the DefaultControllerActivator, which uses the TypeActivatorCache to create the controller.
ActionExecutedContext has property ActionDescriptor. There you can find IsDefined method which gets possibility to check whether one or more instances of the specified attribute type are defined for this member. Check code sample bellow: EDIT: OK, now I get your issue.
The DefaultControllerActivator doesn't attempt to resolve the Controller instance from the DI container itself, only the Controller's dependencies. To demonstrate this behaviour, I've created a simple MVC application, consisting of a single service, and a single controller.
Doing some digging into the MVC source that's pretty much the most optimal way without copying all the methods required to do what you're already doing. However, I don't see why you couldn't cache found actions so that subsequent calls are more performant.
Internally ReflectedControllerDescriptor
also caches the results though there seems to be a bit of overhead since it checks all attributes each time. It looks to be for stuff like HttpPostAttribute
and what not.
My suggestion would be to stick with what you're using rather than cache it yourself. If, for some reason, the way the underlying method works changes you're up to date already and wont' have to worry about changing the way you store cached items.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With