Skip to content

Instantly share code, notes, and snippets.

@cybermaxs
Created September 24, 2013 12:00
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cybermaxs/6683705 to your computer and use it in GitHub Desktop.
Save cybermaxs/6683705 to your computer and use it in GitHub Desktop.
Measure and report performance of asp.net MVC Action Filters using asp.net MiniProfiler. Warning : default namespace is MyApp
[assembly: WebActivator.PreApplicationStartMethod(typeof(MyApp.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(MyApp.App_Start.NinjectWebCommon), "Stop")]
// please add a reference to NInject.MVC3
namespace MyApp.App_Start
{
using System;
using System.Web;
using System.Web.Mvc;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using MyApp.Filters;
using Ninject;
using Ninject.Web.Common;
public static class NinjectWebCommon
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}
/// <summary>
/// Stops the application.
/// </summary>
public static void Stop()
{
bootstrapper.ShutDown();
}
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
return kernel;
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IActionInvoker>().To<ProfiledActionInvoker>();
}
}
}
using System.Web.Mvc;
using StackExchange.Profiling;
namespace MyApp.Filters
{
public class ProfiledActionFilter : IActionFilter, IResultFilter
{
private readonly IActionFilter actionFilter;
private readonly IResultFilter resultFilter;
public ProfiledActionFilter(IActionFilter actionFilter)
{
this.actionFilter = actionFilter;
}
public ProfiledActionFilter(IResultFilter resultFilter)
{
this.resultFilter = resultFilter;
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
using (MiniProfiler.StepStatic("Filter: " + actionFilter.GetType().Name + ".OnActionExecuted", ProfileLevel.Info))
{
actionFilter.OnActionExecuted(filterContext);
}
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
using (MiniProfiler.StepStatic("Filter: " + actionFilter.GetType().Name + ".OnActionExecuting", ProfileLevel.Info))
{
actionFilter.OnActionExecuting(filterContext);
}
}
public void OnResultExecuted(ResultExecutedContext filterContext)
{
using (MiniProfiler.StepStatic("Filter: " + resultFilter.GetType().Name + ".OnResultExecuted", ProfileLevel.Info))
{
resultFilter.OnResultExecuted(filterContext);
}
}
public void OnResultExecuting(ResultExecutingContext filterContext)
{
using (MiniProfiler.StepStatic("Filter: " + resultFilter.GetType().Name + ".OnResultExecuting", ProfileLevel.Info))
{
resultFilter.OnResultExecuting(filterContext);
}
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using StackExchange.Profiling.MVCHelpers;
namespace MyApp.Filters
{
public class ProfiledActionInvoker : ControllerActionInvoker
{
protected override FilterInfo GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
FilterInfo baseFilters = base.GetFilters(controllerContext, actionDescriptor);
WrapFilters(baseFilters.ActionFilters);
WrapFilters(baseFilters.ResultFilters);
return baseFilters;
}
private void WrapFilters(IList<IActionFilter> filters)
{
// Not tested with attribute ordering (may not honor the ordering)
IList<IActionFilter> originalFilters = filters.ToList();
// Avoid wrapping the ProfilingActionFilter (sometimes injected by MVC Mini Profiler) and Attributes that are already wrapped.
IEnumerable<IActionFilter> newFilters = originalFilters
.Select(item =>
{
// ProfilingActionFilter is injected by MVC Mini Profiler
// ProfiledActionFilter is our custom wrapper : do not profile filter already profiled !
if (item.GetType() != typeof(ProfiledActionFilter) && item.GetType() != typeof(ProfilingActionFilter))
return new ProfiledActionFilter(item);
else
return item;
});
filters.Clear();
foreach (IActionFilter actionFilter in newFilters)
{
filters.Add(actionFilter);
}
}
private void WrapFilters(IList<IResultFilter> filters)
{
// Not tested with attribute ordering (may not honor the ordering)
IList<IResultFilter> originalFilters = filters.ToList();
// Avoid wrapping the ProfilingActionFilter (sometimes injected by MVC Mini Profiler) and Attributes that are already wrapped.
IEnumerable<IResultFilter> newFilters = originalFilters
.Select(item =>
{
// ProfilingActionFilter is injected by MVC Mini Profiler
// ProfiledActionFilter is our custom wrapper : do not profile filter already profiled !
if (item.GetType() != typeof(ProfiledActionFilter) && item.GetType() != typeof(ProfilingActionFilter))
return new ProfiledActionFilter(item);
else
return item;
});
filters.Clear();
foreach (IResultFilter actionFilter in newFilters)
{
filters.Add(actionFilter);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment