IAclModule如何工作

时间:2014-10-27 17:37:22

标签: c# mvcsitemapprovider

我想知道这个类IAclModule究竟是如何工作的,我的意思是它通过的过程,它每个循环都有一个实例化来验证用户的访问权限,或者它每次都使用相同的实例?

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

THX。

1 个答案:

答案 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一样。