Reputation: 11
I am trying to implement a thread safe dictionary singleton class for caching purpose.
namespace SingletomDict
{
public sealed class MySingleton:IDisposable
{
private static readonly Lazy<MySingleton> coll = new Lazy<MySingleton>(() => new MySingleton());
private static Dictionary<string, object> mycoll;
public static MySingleton Instance
{
get
{
return coll.Value;
}
}
private MySingleton()
{
mycoll = new Dictionary<string, object>();
}
private void SetProperty<T>(string name, T value)
{
mycoll.Add(name, value);
}
private object GetProperty(string name)
{
object value = mycoll[name];
return value;
}
public dynamic this[string index]
{
get { return GetProperty(index); }
set { SetProperty(index, value); }
}
public void ReSet()
{
mycoll = new Dictionary<string, object>();
}
}
In the main method, I will be invoking the object as
MySingleton.Instance["LS"] = "AAA";
MySingleton.Instance["AB"] = "BBB";
MySingleton.Instance.ReSet();
I did some research to find the correct implementation. But I couldn't find the appropriate example. Thanks
Upvotes: 1
Views: 2264
Reputation: 29222
First declare an interface that describes how you want to use this. Perhaps ICache
with a get and set method. (I'd steer clear of dynamic
.)
public interface ICache
{
T Get<T>(string key);
void Set(string key, object value);
}
Then write an implementation. Your implementation doesn't need to specify what the internals are.
public class Cache : ICache
{
private readonly ConcurrentDictionary<string, object> _cache
= new ConcurrentDictionary<string, object>();
public T Get<T>(string key)
{
object cached;
if(_cache.TryGetValue(key, out cached) && cached is T)
{
return(T) cached;
}
return default(T);
}
public void Set(string key, object value)
{
_cache.AddOrUpdate(key, value, (s, o) => value);
}
}
If you want to make this a singleton, you can make the constructor private and create a static singleton instance. I would lean toward not doing that. It's better for other classes to depend on the ICache
interface than on the implementation, and an interface doesn't have static methods.
Depending on the interface means that you can substitute it with different implementations, like one that depends on MemoryCache
.
public class InMemoryCache : ICache
{
private readonly MemoryCache _cache = MemoryCache.Default;
public T Get<T>(string key)
{
var cached = _cache[key];
return cached is T ? (T) cached : default(T);
}
public void Set(string key, object value)
{
_cache[key] = value;
}
}
If you use a dependency injection (IoC) container you can tell it which implementation of ICache
to use for a class that needs an instance of it, and you can specify that the same instance should be provided each time. That way you get to use a single instance of your class as if it was a singleton without having to code it as a singleton.
Upvotes: 3