StackOverflow异常(基础架构缺陷)

时间:2014-06-24 00:08:50

标签: c# design-patterns singleton stack-overflow lazy-evaluation

我在Jon Skeet's great pattern here之后使用懒惰的单身人士。

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

例如,GetTheme(Context.Current.User.Id)获取当前用户的主题,以及许多其他方法。

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

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

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

我试图通过以下方式处理此问题,使公共属性引用成为检查null引用的私有方法,并尝试确定它是否确实应该{{1} }。

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

我之前尝试过将用户对象本身设置为懒惰,但由于某些奇怪的原因,它在调用时并未实例化,并且仍为null

我正在寻找的是,如何让我的Lazy Singleton的null属性在被调用时进行自我评估,如果它是User,则自我实例化,但是能够人口稠密?

条件是,MVC全局null对象属性User不为空,并且在加载时传递到会话中以在模型中提取,并且用户存在于数据库中用户名作为密钥。

User.Identity.Name

1 个答案:

答案 0 :(得分: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;
      }
    }