0

我正在使用一个懒惰的单身人士,跟随Jon Skeet's great pattern hereStackOverflow异常(基础架构漏洞)

该对象的目的是提供对应用程序中所有其他方法的引用。

例如,GetTheme(Context.Current.User.Id)获取当前用户的主题,其他方法也是如此。

我遇到的问题是如何处理对象已经实例化时的状态变化?

即是说,如果用户访问网站并且未登录,则在创建新用户期间使用Context对象。

但是,登录后,User对象为空,因为它已经实例化。

我试图通过以下方式处理这个问题,使公共属性引用一个私有方法来检查null引用,并试图确定它是否确实应该是null

不幸的是,这会变成一个无限循环并且每次都崩溃。

我以前试过让用户对象本身很懒,但是由于一些奇怪的原因,它在调用时并没有实例化,并且仍然是null

我在找什么,我怎样才能使我懒惰单身人士的User属性在被调用时自我评估,如果它是null,但是能够被填充,则实例化自己?

条件是,MVC Global User对象属性User.Identity.Name不为空,并且在加载时传递到会话中以便在模型中拉出,并且用户以用户名作为关键字存在于数据库中。

public sealed class Context 
{ 
    public static Context Current { get { return lazy.Value; } } 
    private static readonly Lazy<Context> lazy = 
     new Lazy<Context>(() => new Context()); 
    public UserMeta User { get { return _meta(); } } 

    private Context() 
    { 
     Deployment = GetCurrentDeploymentType(); 
     Device = (Device)HttpContext.Current.Session["CurrentDevice"]; 
    } 

    private UserMeta _meta() 
    { 
     //If the current object is null, 
     //but the user has been authenticated, populate the object 
     if (Current.User == null && 
      !string.IsNullOrEmpty((string)HttpContext.Current.Session["UserEmail"])) 
     { 
      //check that the user is in the database first 
      var _userTry = 
       Sql.Read.UserByEmail((string)HttpContext.Current.Session["UserEmail"]); 
      if (_userTry == null) 
      { 
       return new UserMeta(
       new UserMeta((string)HttpContext.Current.Session["UserEmail"])); 
      } 
      return null; 
     } 
     //If the Current Instance already has a populated User Object, 
     //just use that 
     else if (Current.User != null) 
      return Current.User; 
     else 
      return null; 
    } 
} 

回答

1

如果使用的是私有字段,它会解决这个问题

public sealed class Context 
{ 
    private UserMeta _user = null; 

    public static Context Current { get { return lazy.Value; } } 
    private static readonly Lazy<Context> lazy = new Lazy<Context>(() => new Context()); 
    public UserMeta User 
    { 
     get 
     { 
      if (_user == null) _user =_meta(); 
      return _user; 
     } 
    } 

    private Context() 
    { 

    private UserMeta _meta() 
    { 
     if (!string.IsNullOrEmpty((string)HttpContext.Current.Session["UserEmail"])) 
     { 
      //check that the user is in the database first 
      var _userTry = 
      Sql.Read.UserByEmail((string)HttpContext.Current.Session["UserEmail"]); 
      if (_userTry == null) 
      { 
      return new UserMeta(
      new UserMeta((string)HttpContext.Current.Session["UserEmail"])); 
      } 
      return null; 
     } 
    }