我想知道这个类IAclModule究竟是如何工作的,我的意思是它通过的过程,它每个循环都有一个实例化来验证用户的访问权限,或者它每次都使用相同的实例?
我问这个因为我需要实现自己的逻辑,因为默认的AuthorizeAttributeAclModule和XmlRolesAclModule一直很慢。
THX。
答案 0 :(得分:1)
AclModule由DI(依赖注入)容器实例化。使用内部DI容器时,它由SiteMapFactoryContainer.ResolveAclModule method实例化。但是,无论是使用内部DI还是外部DI,实例都会在SiteMap对象的生命周期内(因此通过缓存)保存在SiteMapPluginProvider类的私有字段中,而该字段又位于SiteMapPluginProvider类的私有字段中。 SiteMap类。因此,每个SiteMap有一个实例,默认情况下,每次缓存过期时都会创建一个实例(默认情况下每5分钟一次)。
AuthorizeAttributeAclModule已经过彻底测试,并且已经过优化。但是,它为每个节点创建了相关控制器类和AuthorizeAttribute类的实例,因此如果您的控制器或AuthorizeAttribute的任何自定义实现在构造函数中执行了太多工作,您可能会遇到性能问题的问题。
要解决此问题,您应该通过Controller构造函数将依赖项注入每个控制器,而不是在构造函数内部进行繁重的工作。如果使用dependency injection container in conjunction with a custom IControllerFactory,则可以从控制器外部控制依赖项的生存期。如下面的示例所示,使用此方法时,您可以为MyController的每个实例使用相同的IMyRepository实例。
public class MyController : Controller
{
public MyController(IMyRepository repository)
{
if (repository == null)
throw new ArgumentNullException("repository");
this.repository = repository;
}
private readonly IMyRepository repository;
public ActionResult Index()
{
var items = this.repository.GetList()
return View(items);
}
}
这是设计控制器的推荐最佳实践,但是如果创建成本太高,您还可以请求缓存依赖项,这样每个控制器实例都不会非常耗时。如果每个请求多次实例化,则创建。
public class MyController : Controller
{
public MyController()
{
this.repository = this.GetOrCreateRepository();
}
private readonly IMyRepository repository;
private IMyRepository GetOrCreateRepository()
{
var key = "MyControllerRepository";
var result = HttpContext.Items[key];
if (result == null)
{
// If the expensive dependency wasn't already created for this request, do it now
result = new MyRepository();
// Save the instance in the request, so the next time this controller is created,
// it doesn't have to instantiate it again.
HttpContext.Items[key] = result;
}
return result;
}
public ActionResult Index()
{
var items = this.repository.GetList()
return View(items);
}
}
此外,如果您有自定义AuthorizeAttribute(s),您应该确保他们没有做任何工作,除了检查用户是否被授权,delegating the real work to a handler与Microsoft一样。