我在ASP.NET MVC网站上将越来越多的面向方面的问题转移到ActionFilters中。因此,我怀疑我的一些性能瓶颈可能已经转移到ActionFilters中,而不知道它们的性能是什么。我想挂钩到MVC的ActionFilter创建过程来包装每个ActionFilter,以便我可以记录该ActionFilter执行的时间。
到目前为止,我已经找到了以下网站链接,提示如何开始这条路,但我不确定如何实际包装每个ActionFilter。
答案 0 :(得分:3)
您应该从ControllerActionInvoker派生和新类,并覆盖GetFilters方法。在此方法中,您应该创建一个诊断包装类的新实例,该实例包含封装实际过滤器的相同接口(IActionFilter)。 GetFilters作为InvokeAction方法的一部分被调用(也可以被覆盖),但GetFilters可能是最干净的。
另外你也可以尝试覆盖InvokeActionMethodWithFilters,这是实际调用动作过滤器的地方但是这可能会很麻烦,但如果你刚添加了一些东西可能会好的 像:
protected override ActionExecutedContext InvokeActionMethodWithFilters(ControllerContext controllerContext, IList<IActionFilter> filters, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters)
{
Stopwatch diagWatch = Stopwatch.StartNew();
var context = base.InvokeActionMethodWithFilters(controllerContext, filters, actionDescriptor, parameters);
diagWatch.Stop();
return context;
}
要实现ControllerActionInvoker类,请参阅:
public class DiagControllerActionInvoker : ControllerActionInvoker
{
protected override FilterInfo GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
FilterInfo baseFilters = base.GetFilters(controllerContext, actionDescriptor);
//Add new filters
//e.g. baseFilters.ActionFilters.Insert(0, actionFilter);
return baseFilters;
}
}
要实际指定调用自定义ControllerActionInvoker,您需要创建一个DefaultControllerFactory实现,如:
public class SiteControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType == null)
{
return null;
}
// Create controller class. Here.
IController controller = (IController)Activator.CreateInstance(controllerType)
if (typeof(Controller).IsAssignableFrom(controllerType))
{
Controller controllerInstance = controller as Controller;
if (controllerInstance != null)
{
controllerInstance.ActionInvoker = new DiagControllerActionInvoker();
}
}
return controller;
}
}
就像设置在你的应用程序代码中一样:
ControllerBuilder.Current.SetControllerFactory(new SiteControllerFactory());
答案 1 :(得分:1)