Hydrogen Extensions for ASP.NET MVC 5 Alpha Release
First published on March 20, 2017I’m happy to share the first alpha release of my extensions library for ASP.NET MVC 5 which adds support for async filters.
You can download the library from NuGet and the source is available on GitHub.
You can read about my journey to get here:
- Part 1 - The Current Landscape
- Part 2 - Refactoring AsyncControllerActionInvoker
- Part 3 - Async Filter API
Getting started
First we need to swap out the default implementation IAsyncActionInvoker
with Hydrogen.Extensions.Mvc5.Async.ControllerActionInvokerEx
. There are two ways to do this:
1) Set the ActionInvoker
property of a controller when it’s constructed:
public class HomeController : Controller
{
public HomeController()
{
ActionInvoker = ControllerActionInvokerEx.Instance;
}
}
2) Using your DI container of choice, register Hydrogen.Extensions.Mvc5.Async.ControllerActionInvokerEx
as an implementation of IAsyncActionInvoker
.
For example (using Autofac):
builder.RegisterInstance(ControllerActionInvokerEx.Instance)
.As<IAsyncActionInvoker>()
.SingleInstance();
Note that ControllerActionInvokerEx
can be used as a singleton. It doesn’t maintain any state.
Creating an async filter
You may create a subclass of AsyncActionFilterAttribute
or AsyncExceptionFilterAttribute
and override the async methods.
For example:
public class MyAsyncActionFilterAttribute : AsyncActionFilterAttribute
{
public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
// Execute code before the action is invoked.
// You can "short-circuit" the action by setting 'context.Result'
// and returning before calling 'next()'.
// The implementation is responsible for calling 'next()'.
var actionExecutedContext = await next().ConfigureAwait(false);
// Execute code after the action is invoked
}
public override async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
{
// Execute code before the result is invoked.
// You can "short-circuit" the action by setting 'context.Canceled = true'
// and returning before calling 'next()'.
// The implementation is responsible for calling 'next()'.
var resultExecutedContext = await next().ConfigureAwait(false);
// Execute code after the result is invoked
}
}
Alternately you may implement any of the async filters:
IAsyncActionFilter
IAsyncResultFilter
IAsyncExceptionFilter
IAsyncAuthorizationFilter
Unfortunately, for compatibility reasons, you must also implement the non-async version of these filters (e.g. void OnActionExecuting(ActionExecutingContext filterContext)
). However, these methods can be a NOOP since the code is never executed by ControllerActionInvokerEx
.
This library, currently, does not implement as async version of IAuthenticationFilter
.
This is an alpha release
I fully expect there to be bugs, however I hope to use it in real production code soon.
Maybe one day this code, or some derivation there of, can make it into an official release.
I hope someone else might find this library useful. And I’d appreciate feedback, comments, or contributions (including bug reports)!
Comments
Comments are not moderated. But I reserve the right to delete anything hostile, offensive, or SPAMy.