安全调整功能依赖于创建控制器实例every节点以确定当前用户上下文是否具有访问权限。
造成这种缓慢的最可能原因是您的控制器(或其基类)在构造函数中进行了太多繁重的处理。
public class HomeController
{
public HomeController() {
// Lots of heavy processing
System.Threading.Thread.Sleep(300);
};
}
上面的示例将在页面中为代表操作方法的每个节点增加 300 毫秒的页面加载时间。HomeController
。如果您的其他控制器在实例化期间也有繁重的处理,它们也会为每个页面加载增加额外的时间。
当遵循 DI 最佳实践时,这不是问题,因为在创建控制器实例后,外部服务中会进行大量处理。
public interface IHeavyProcessingService
{
IProcessingResult DoSomethingExpensive();
}
public class HeavyProcessingService : IHeavyProcessingService
{
public HeavyProcessingService() {
}
public IProcessingResult DoSomethingExpensive() {
// Lots of heavy processing
System.Threading.Thread.Sleep(300);
}
}
public class HomeController
{
private readonly IHeavyProcessingService heavyProcessingService;
// The constructor does no heavy processing. It is deferred until after
// the instance is created by HeavyProcessingService.
// The only thing happening here is assignment of dependencies.
public HomeController(IHeavyProcessingService heavyProcessingService) {
if (heavyProcessingService == null)
throw new ArgumentNullException("heavyProcessingService");
this.heavyProcessingService = heavyProcessingService;
};
public ActionResult Index()
{
var result = this.heavyProcessingService.DoSomethingExpensive();
// Do something with the result of the heavy processing
return View();
}
public ActionResult About()
{
return View();
}
public ActionResult Contact()
{
return View();
}
}
请注意,在上面的示例中,构造函数中没有发生繁重的处理?这意味着创建一个实例HomeController
很便宜。这也意味着不需要进行繁重处理的操作方法(如About()
and Contact()
在示例中)不会受到所需的繁重处理的影响Index()
.
如果不使用 DI,MVC 仍然要求为每个请求创建一个新的控制器实例(控制器实例永远不会在用户或操作方法之间共享)。不过,在这种情况下,每个用户的情况并不那么明显,因为每个用户仅创建 1 个实例。基本上,MvcSiteMapProvider
由于您的应用程序预先存在问题(您现在可以修复),速度正在减慢。
即使您不使用 DI,最好的做法仍然是将繁重的处理推迟到创建控制器实例之后。
public class HomeController
{
private readonly IHeavyProcessingService heavyProcessingService;
public HomeController() {
this.heavyProcessingService = new HeavyProcessingService();
};
public ActionResult Index()
{
var result = this.heavyProcessingService.DoSomethingExpensive();
// Do something with the result of the heavy processing
return View();
}
}
但是,如果无法将繁重的处理转移到应用程序中的外部服务中,您仍然可以通过将处理转移到另一种方法中来推迟处理,直到需要时为止,这样创建控制器实例的成本就不会太高。
public class HomeController
{
public HomeController() {
};
private IProcessingResult DoSomethingExpensive() {
// Lots of heavy processing
System.Threading.Thread.Sleep(300);
}
public ActionResult Index()
{
var result = this.DoSomethingExpensive();
// Do something with the result of the heavy processing
return View();
}
}