2014-06-24 109 views
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; 
     } 
    }