简体   繁体   中英

ASP MVC 5 Disposing of Object Context

I have a extension method which needs to query the database to check user permissions as follows:

public static bool HasPermission(this IPrincipal user, string permission)
{
    ApplicationUser appUser = ApplicationUserManager.GetUser(user.Identity.GetUserId());

    return  appUser.HasPermission(permission);

}

Currently the call to get the application user is implemented as follows:

 public static ApplicationUser GetUser(string userId)
 {
        return GetUser(new ApplicationDbContext(), userId);
 }

 public static ApplicationUser GetUser(ApplicationDbContext context, string userId)
 {
        ApplicationUser _retVal = null;
        try
        {
            _retVal = context.Users.Where(p => p.Id == userId).FirstOrDefault();
        }
        catch (Exception)
        {
        }

        return _retVal;
 }

Now in my views and controller actions I frequently call User.HasPermission() method. So I'm considering the performance implication of frequently calling this method. Would it be better to implement the call wrapping it inside a using statement as follows so that the context gets disposed or I'm I correct in how I've already implemented it above?

public static bool HasPermission(this IPrincipal user, string permission)
    {
        using (ApplicationDbContext _context = new ApplicationDbContext())
        {
            var userId = user.Identity.GetUserId();
            ApplicationUser applicationUser = _context.Users.Where(p => p.Id == userId).FirstOrDefault();
            return applicationUser.HasPermission(permission);
        }
    }

Disposing your db context is a good idea. I would put the context into a wrapper class and handle the app-specific db requests through specific methods. eg GetUser(id), GetAllItems(), GetSingleItem(id), GetItemsByCategory(category), etc. Using c# generics, repositories and base classes can help with the repetetive nature of these types of calls when you have many different asset types.

This ensures your dbcontext is called and disposed for each instance its required. eg

On One Page Request

  • GetUser (open-dispose)
  • GetSomethingElse (open-dispose AGAIN)
  • SaveSomething(open-dispose AGAIN)

Also, I would add the user's entire permission set directly to the User class when it's loaded, rather than making separate DB calls for each "HasPermission" request.

Use a cache mechanism (ie. MemoryCache) to store that user object, along with their permission set. This same cache mechanism can be used to store app data as well. There are some pre-built ones out there if you google around but setting up a basic one isn't difficult.

With caching a user requests something from your site, and it already knows who they are and what they have access to without ever having to touch the DB (again), for at least a few minutes, perhaps longer depending on how often permissions change. 5-15 minute permission cache is pretty reasonable. Cache removal techniques can ensure the permission set is always accurate, assuming you control the permission store itself or have hooks that can trigger updates on your end.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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