简体   繁体   中英

Singleton dictionary is not being singleton

I have a dictionary in a singleton class. I am saving there the pair , every time I access to that dictionary from the method that is creating the token it shows all the credentials that I've stored there.

But when I access from another class in another project of the solutions it displays the dictionary empty. Can anybody tell me why this happens?

This is the class that manage the dictionary:

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;
        }
    }
}

This is the method that insert the key,value pair in the dictionary:

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);
    }

This is the method where I access the dictionary, from here I can see that it's empty:

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;
    }

I already solved my problem, but I'll let my solution here in case could be useful for somebody.

The problem is that if you are running two different projects, that will mean two different process, so, what I wanted to do is pretty impossible. I used Redis for this and it is working well.

This is an example of Redis use:

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;

    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM