简体   繁体   English

IAclModule如何工作

[英]How IAclModule works

I want to know how exactly this class IAclModule works, I mean the process it pass, it's instanceaded one each loop to verify the access for the user, or it's used the same instance each time? 我想知道IAclModule这个类到底是如何工作的,我的意思是它通过的过程,每个循环实例化一个以验证用户的访问权限,还是每次都使用相同的实例?

I ask that because I need to implement my own logic since the default AuthorizeAttributeAclModule and XmlRolesAclModule have been wayyy to slow. 我问这是因为我需要实现自己的逻辑,因为默认的AuthorizeAttributeAclModule和XmlRolesAclModule太慢了。

Thx. 谢谢。

The AclModule is instantiated by the DI (dependency injection) container. AclModule由DI(依赖注入)容器实例化。 When using the internal DI container, it is instantiated by the SiteMapFactoryContainer.ResolveAclModule method . 使用内部DI容器时,它由SiteMapFactoryContainer.ResolveAclModule方法实例化。 However, whether using internal or external DI, the instance is kept alive for the lifetime of the SiteMap object (and therefore by the cache) by being stored in a private field of the SiteMapPluginProvider class, which in turn is in a private field of the SiteMap class. 但是,无论使用内部DI还是外部DI,实例都通过存储在SiteMapPluginProvider类的私有字段中而保持活动状态(并因此在缓存中),而该实例又位于SiteMapPluginProvider类的私有字段中。 SiteMap类。 Therefore, there is 1 instance per SiteMap which by default only gets created each time the cache expires (1 time every 5 minutes by default). 因此,每个SiteMap有1个实例,默认情况下,该实例仅在每次缓存过期时才创建(默认情况下每5分钟1次)。

The AuthorizeAttributeAclModule has been tested pretty thoroughly and has been optimized pretty well. AuthorizeAttributeAclModule已通过相当全面的测试,并且已进行了相当不错的优化。 However, it creates an instance of the related controller class and the AuthorizeAttribute class for each node , so if your Controllers or any custom implementations of AuthorizeAttribute are doing too much work in the constructor, you could run into performance issues. 但是,它为每个节点创建了相关的控制器类和AuthorizeAttribute类的实例,因此,如果您的Controller或AuthorizeAttribute的任何自定义实现在构造函数中做了太多工作,则可能会遇到性能问题。

To fix this, you should aim to inject dependencies into each controller through the Controller constructor instead of doing heavy lifting inside of the constructor. 要解决此问题,您应该旨在通过Controller构造函数将依赖项注入每个控制器,而不是在构造函数内部进行繁重的工作。 If you use a dependency injection container in conjunction with a custom IControllerFactory , you can control the lifetime of the dependencies externally from the controller. 如果将依赖项注入容器与自定义IControllerFactory结合使用 ,则可以从控制器外部控制依赖项的生存期。 As shown in the example below, when using this approach you could use the same instance of IMyRepository for every instance of MyController. 如下例所示,使用这种方法时,可以为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);
    }
}

That is a recommended best practice for the design of your controllers, but in a pinch, you could also request-cache your dependencies if they are expensive to create so each controller instance won't be so time-consuming to create if it is instatiated more than one time per request. 对于控制器的设计,这是推荐的最佳实践,但是在紧要关头,如果创建依赖项的开销很大,那么也可以请求缓存您的依赖项,因此每个控制器实例的创建都不会那么耗时每个请求超过一次。

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);
    }
}

Also, if you have custom AuthorizeAttribute(s) you should make sure they are not doing any work except checking whether the user is authorized, delegating the real work to a handler the same way that Microsoft does. 此外,如果您具有自定义的AuthorizeAttribute(s),则应确保他们除了检查用户是否被授权外,不执行任何其他工作, 将真实工作委托给处理程序 ,方法与Microsoft相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM