单例字典不是单例

Singleton dictionary is not being singleton

我在单例中有一本字典class。我正在那里保存这对,每次我从创建令牌的方法访问该字典时,它都会显示我存储在那里的所有凭据。

但是当我从解决方案的另一个项目中的另一个 class 访问时,它显示字典为空。谁能告诉我为什么会这样?

这是管理字典的class:

public class UserAccessToken
{
    public Dictionary<string, string> UserDictionary { get; set; }

    private static UserAccessToken _instance;

    private UserAccessToken() { }

    public static UserAccessToken Instance
    {
        get
        {
            if (_instance == null)
                _instance = new UserAccessToken
                {
                    UserDictionary = new Dictionary<string, string>()
                };
            return _instance;
        }
    }
}

这是在字典中插入键值对的方法:

public override Task TokenEndpointResponse(OAuthTokenEndpointResponseContext context)
    {
        var accessToken = context.AccessToken;

        if (context.Properties.Dictionary.ContainsKey("userName"))
        {
            var username = context.Properties.Dictionary["userName"];
            // If I access here multiple times the singleton works
            UserAccessToken.Instance.UserDictionary[username] = accessToken;
        }
        return Task.FromResult<object>(null);
    }

这是我访问字典的方法,从这里我可以看到它是空的:

private bool IsTokenValid(HttpContextBase httpContext)
    {
        var username = httpContext.User.Identity.Name;
        var userTokens = UserAccessToken.Instance.UserDictionary;
        var tokenToAccess = httpContext.Request.Headers["Authorization"];
        tokenToAccess = tokenToAccess.Replace("Bearer ", "");
        if (userTokens.ContainsKey(username))
        {
            var token = userTokens[username];
            if (token == tokenToAccess) return true;
        }
        return true;
    }

我已经解决了我的问题,但我会把我的解决方案放在这里以防对某些人有用。

问题是,如果你是 运行 两个不同的项目,那将意味着两个不同的过程,所以,我想做的事情是不可能的。我为此使用了 Redis,它运行良好。

这是Redis使用的例子:

public class CallManagerCache : ICallManagerMethods{


    private static Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() => ConnectionMultiplexer
        .Connect(CloudConfigurationManager.GetSetting("RedisConnectionString")));

    public static ConnectionMultiplexer cacheConnection
    {
        get
        {
            return lazyConnection.Value;
        }
    }

    /// <summary>
    ///     Here you save the value in cache, you get the connection, then StringSetAsync is in charge of saving the value
    /// </summary>
    /// <param name="name"></param>
    /// <param name="template"></param>
    public async Task UpdateCallInstance(int id, byte[] data, bool instanceForCallback = false, TimeSpan? timespan = null)
    {
        var cache = cacheConnection.GetDatabase();
        await cache.StringSetAsync(instanceForCallback ? $"Call_{id}" : id.ToString(), data, timespan ?? new TimeSpan(0, 0, 15, 0));
    }

    /// <summary>
    ///     Here you get the value in cache, you get the connection, then StringGetAsync is in charge of getting the value
    /// </summary>
    /// <param name="name"></param>
    /// <param name="template"></param>
    public async Task<CallInstance> GetById(int id, bool isForCallback)
    {
        var cache = cacheConnection.GetDatabase();

        var callInstance = new CallInstance
        {
            Id = id,
            InstanceData = await cache.StringGetAsync(isForCallback ? $"Call_{id}" : id.ToString())
        };
        return callInstance;

    }
}