依赖于其他实例变量的实例变量

时间:2017-03-23 06:02:58

标签: c# asp.net-mvc asp.net-identity

我想知道设置一个类变量的正确方法,该类变量将在类中的大多数/所有方法中使用,这依赖于正在使用的其他类变量和属性。

我不相信我能够将它放在构造函数中,因为它依赖于设置的属性和变量直到构造函数执行后才会设置。

我使用的是asp.net Identity。

要设置的变量:

private bool userIsSysAdmin;

userIsSysAdmin将取决于:

userIsSysAdmin = UserManager.GetRoles(user.Id)
      .Any(u => u == "Sys Admin");

请注意使用 user UserManager

类签名,属性和实例变量:

    public class CompanyController : Controller 
    {
       public CompanyController()
       {
       }

       public CompanyController(ApplicationUserManager userManager, ApplicationRoleManager roleManager)
       {
           UserManager = userManager;
           RoleManager = roleManager;
       }

       private ApplicationUserManager _userManager;
       public ApplicationUserManager UserManager
       {
           get
           {
               return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
           }
           private set
           {
               _userManager = value;
           }
       }

       ApplicationUser user = System.Web.HttpContext.Current.GetOwinContext()
           .GetUserManager<ApplicationUserManager>()                               
           .FindById(System.Web.HttpContext.Current.User.Identity.GetUserId());

2 个答案:

答案 0 :(得分:1)

您可以使用延迟加载的属性。这意味着您将值保留为未初始化,直到您第一次需要它为止。您还可以在设置新用户管理器时重置用户的值。这样您就可以确保用户始终与用户管理器匹配。

   public ApplicationUserManager UserManager
   {
       get
       {
           return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
       }
       private set
       {
           _userManager = value;
           _user = null;
       }
   }

   ApplicationUser _user;
   private ApplicationUser User
   {
       get
       {
           if (_user == null)
           {
               _user = System.Web.HttpContext.Current.GetOwinContext()
                   .GetUserManager<ApplicationUserManager>()                               
                   .FindById(System.Web.HttpContext.Current.User.Identity.GetUserId());
           }
           return _user;
       }
   }

答案 1 :(得分:1)

由于您几乎在控制器的每个方法中都需要它,这是您的类的自然依赖。

在这种情况下,可以在控制器的构造函数中计算。但是,在实际需要UserUserIsSysAdmin属性之前,您不希望查询数据库。

因此,您可以使用Lazy<T>来解决该问题:

public class CompanyController : Controller 
{
    private readonly Lazy<ApplicationUser> user;

    private readonly Lazy<bool> userIsSysAdmin;

    //Not sure why you need parameterless this constructor?
    public CompanyController()
    {
        this.user = new Lazy<ApplicationUser>(() => UserManager.FindById(System.Web.HttpContext.Current.User.Identity.GetUserId()));
        this.userIsSysAdmin = new Lazy<bool>(() => UserManager.GetRoles(User.Id).Any(u => u == "Sys Admin"));
    }

    public CompanyController(ApplicationUserManager userManager, ApplicationRoleManager roleManager)
    {
        UserManager = userManager;
        RoleManager = roleManager;
        this.user = new Lazy<ApplicationUser>(() => UserManager.FindById(System.Web.HttpContext.Current.User.Identity.GetUserId()));
        this.userIsSysAdmin = new Lazy<bool>(() => UserManager.GetRoles(User.Id).Any(u => u == "Sys Admin"));
    }

    public ApplicationUser User
    {
        get { return this.user.Value; }
    }

    public bool UserIsSysAdmin
    {
        get { return this.userIsSysAdmin.Value; }
    }

    private ApplicationUserManager _userManager;
    public ApplicationUserManager UserManager
    {
        get
        {
            return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
        }
        private set
        {
            _userManager = value;
        }
    }
}

应根据您的具体逻辑和用例设置UserUserIsSysAdmin属性的访问修饰符。