IAclModule的工作原理

本文关键字:工作 IAclModule | 更新日期: 2023-09-27 18:28:10

我想知道这个类IAclModule到底是如何工作的,我指的是它通过的进程,它在每个循环中实例化一个以验证用户的访问权限,还是每次都使用同一个实例?

我之所以这么问,是因为我需要实现自己的逻辑,因为默认的AuthorizeAttributeAclModule和XmlRolesAclModule一直很慢。

Thx。

IAclModule的工作原理

AclModule由DI(依赖注入)容器实例化。当使用内部DI容器时,它由SiteMapFactoryContainer.ResolveAclModule方法实例化。但是,无论是使用内部DI还是外部DI,实例都通过存储在SiteMapPluginProvider类的私有字段中而在SiteMap对象的生存期内保持活动状态(因此通过缓存保持活动状态),而该私有字段又位于SiteMap类的私有域中。因此,每个SiteMap有一个实例,默认情况下,只有在缓存到期时才会创建该实例(默认情况下每5分钟创建一次)。

AuthorizeAttributeAclModule经过了非常彻底的测试,并且优化得非常好。但是,它为每个节点创建相关控制器类和AuthorizeAttribute类的实例,因此,如果控制器或AuthorizeAttribute的任何自定义实现在构造函数中做了太多工作,则可能会遇到性能问题。

要解决这个问题,您应该通过controller构造函数将依赖项注入每个控制器,而不是在构造函数内部进行繁重的工作。如果将依赖项注入容器与自定义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,则应确保他们除了检查用户是否获得授权外,没有做任何工作,并以与Microsoft相同的方式将实际工作委派给处理程序。