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
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.
Related
I'm having a problem when trying to register my types using their static constructors, with the following factory:
public class Factory<T>
{
public static Factory<T> Instance { get { return _instance; } }
private static Factory<T> _instance = new Factory<T>();
private Factory() { }
static Factory() { }
static Dictionary<string, Type> _registeredType = new Dictionary<string, Type>();
public void Register(string id, T obj)
{
if (obj.GetType().IsAbstract || obj.GetType().IsInterface)
throw new ArgumentException("Cannot create instance of interface or abstract class");
_registeredType.Add(id, obj.GetType());
}
public T Create(string id, params object[] parameters)
{
Type type;
if(!_registeredType.TryGetValue(id, out type))
throw new UnsupportedShapeException(id);
return (T)Activator.CreateInstance(type, parameters);
}
}
Then if I use a static constructor for registration it doesn't work:
public interface IShape
{
string print { get; }
}
public class Circle : IShape
{
static Circle()
{
Factory<IShape>.Instance.Register("Circle", new Circle());
}
public string print
{
get
{
return "Circle";
}
}
}
Where am I going wrong? The factory appears to set up fine but I just can't get the ctor to work. Cheers.
It's not an answer but an advice. First, when you use generic class actually CLR creates class for every implementation. This classes will have different static variables and you can not use one factory for all classes. The good news is that you can use generic methods instead of generic class. And you even do not need to create an instance of T object:
public class Factory
{
public static Factory Instance { get { return _instance; } }
private static Factory _instance = new Factory();
private Factory() { }
static Dictionary<string, Type> _registeredType = new Dictionary<string, Type>();
public void Register<T>(string id)
{
var type = typeof(T);
if (type.IsAbstract || type.IsInterface)
throw new ArgumentException("Cannot create instance of interface or abstract class");
_registeredType.Add(id, type);
}
public T Create<T>(string id, params object[] parameters)
{
Type type;
if(!_registeredType.TryGetValue(id, out type))
throw new UnsupportedShapeException(id);
return (T) Activator.CreateInstance(type, parameters);
}
}
Now you can use Factory to register and resolve objects:
Factory.Instance.Register<Circle>("Circle");
var firstCircle = Factory.Instance.Create<Circle>("Circle");
var secondCircle = Factory.Instance.Create<IShape>("Circle");
I am not 100% sure I know what you are going after, however, it would probably be best to make controller'esqe classes that contain your factory instantiation. However, constructor injection will not work on static classes or descendants.
public static class StaticFactoryClassController
{
private static readonly IStaticFactoryService service=AppServiceFactory.Instance.Create<IStaticFactoryService>();
public static void DoSomething()
{
Service srv = new StaticFactoryClassService(service);
srv.DoSomething();
}
}
And with that you could create a service class--
public class StaticFactoryClassService
{
private readonly IStaticFactoryService service;
public StaticFactoryClassService(IStaticFactoryService service)
{
this.service = service;
}
public void DoSomething()
{
this.service.DoSomething();
}
}
And finally your binding interface--
public interface IStaticFactoryService
{
DoSomething();
}
I've just created some kind of generic repository, it seems to be working, my only problem is, is there any solution to avoid to use public constructor in classes what has to be instantiated to the repository?
My code is here:
public sealed class repository
{
private static readonly object _lock = new object();
private static readonly object _syncroot = new object();
private static volatile repository _instance;
private static readonly Dictionary<int, object> _dict
= new Dictionary<int, object>();
private repository()
{
}
public static repository instance
{
get
{
if (_instance == null)
{
lock (_lock)
{
if (_instance == null) _instance = new repository();
}
}
return _instance;
}
}
public void allocate<Tc>(int id, object constructor_param) where Tc : Irepository<Tc>, new()
{
lock (_syncroot)
{
if (!_dict.ContainsKey(id))
{
var n = new Tc();
_dict.Add(id, n.New(constructor_param));
}
}
}
public T get<T>(int id)
{
lock (_syncroot)
{
return (T) _dict[id];
}
}
}
public interface Irepository<out T>
{
T New(object constructor_param);
}
public class RpSupportedClass : Irepository<RpSupportedClass>
{
public object _constructor_param;
private RpSupportedClass(object constructor_param)
{
_constructor_param = constructor_param;
}
public RpSupportedClass()
{
}
public RpSupportedClass New(object constructor_param)
{
return new RpSupportedClass(constructor_param);
}
}
So the problem is that I have to create a default public constructor:
public RpSupportedClass()
{
}
...because of type parameter. I need type parameter by this way because I would like to use parameter in class instantiate sometimes.
Is there any way out?
Thank you!
Is the following tread safe in a singleton pattern? I used the fourth singleton pattern in http://csharpindepth.com/Articles/General/Singleton.aspx
I'm concerned using an output parameter will break the whole principal.
public sealed class eCacheContent
{
private static readonly eCacheContent instance = new eCacheContent();
private ICacheManager _Cache = CacheFactory.GetCacheManager(ConfigurationManager.AppSettings["ContentCache"].ToString());
// for access method control locking
private static object syncRoot = new object();
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static eCacheContent() { }
private eCacheContent() { }
public static eCacheContent Instance
{
get
{
return instance;
}
}
public bool TryGetValue(string key, out eContent output)
{
lock (syncRoot)
{
if (Contains(key))
{
ObjectCloner helper = new ObjectCloner();
eContent tmp = (eContent)this._Cache.GetData(key);
output = helper.Clone(tmp);
return true;
}
output = new eContent();
return false;
}
}
public void Add(string key, object value)
{
// Initiase the helper class for cloning
if (CheckKeyIfValid(key))
{
ObjectCloner helper = new ObjectCloner();
// Remove if already exist
this.Remove(key);
// Add carbon copy
_Cache.Add(key, helper.Clone(value));
}
}
public void Flush()
{
_Cache.Flush();
}
private bool Contains(string key)
{
if (CheckKeyIfValid(key))
return _Cache.Contains(key);
else
return false;
}
private void Remove(string key)
{
if (Contains(key))
{
_Cache.Remove(key);
}
}
private bool CheckKeyIfValid(string key)
{
if ((key != null) && (key.Trim().Length != 0))
return true;
return false;
}
}
I'm concerned using an output parameter will break the whole principal.
In what way do you think an out parameter breaks the principle of a Singleton? By definition a singleton class "restricts the Instantiation of a class to one object" - your Instance property ensures that.
Your TryGetValue method is a helper method for pulling out cached versions of eContent, this is completely separate from your eCacheContent class.
I want to implement a wrapper class for a Dictionary that maps a Type to a generic List of that Type. For example:
**Key** **Value**
typeof(InterfaceA), List<InterfaceA>
typeof(InterfaceB), List<InterfaceB>
typeof(MyClass), List<MyClass>
...
I then want to interact with the wrapper class by using types.
public void NewEntry<T>()
{
MyDict.Add(typeof(T), new List<T>());
}
public List<T> GetEntry<T>()
{
return MyDict[typeof(T)];
}
public void RemoveEntry<T>()
{
MyDict.Remove(typeof(T));
}
Is there any elegant way to do this?
EDIT: to clarify, the point of this is so that with
GetEntry<MyInterface>()
the items in the list are guaranteed to follow the contract of MyInterface. Each entry would have a different Type key, and each List of items would follow the contract of that Type.
You could use the following static class
public static class GenericLists
{
private static Dictionary<Type, object> MyDict = new Dictionary<Type, object>();
public static void NewEntry<T>()
{
MyDict.Add(typeof(T), new List<T>());
}
public static List<T> GetEntry<T>()
{
return (List<T>)MyDict[typeof(T)];
}
public static void RemoveEntry<T>()
{
MyDict.Remove(typeof(T));
}
}
Or you could use
public class GenericLists<T>
{
private Dictionary<Type, List<T>> MyDict = new Dictionary<Type, List<T>>();
public void NewEntry()
{
MyDict.Add(typeof(T), new List<T>());
}
public List<T> GetEntry()
{
return MyDict[typeof(T)];
}
public void RemoveEntry()
{
MyDict.Remove(typeof(T));
}
}
if you really want to initialize it, but I think the static will work better.
If you're willing to store everything statically, you can use the type system:
static class MyDict {
private static class Data<T> {
public static readonly List<T> items = new List<T>();
}
public static List<T> Get<T>() { return Data<T>.items; }
public static void Add<T>(T item) { Data<T>.items.Add(item); }
}
Note that this makes it impossible to remove a key (you can't unload a type), although you can Clear() it.
You can do it as an instance-based class also (see below), but my preference, if it works for you, is to use a static variable in a static class as SLaks demonstrated in the "use the type system" post.
public class GenericTypeListDictionary
{
private readonly Dictionary<Type, object> _dictionaryOfLists = new Dictionary<Type, object>();
public List<T> NewEntry<T>()
{
var newList = new List<T>();
_dictionaryOfLists.Add(typeof(T), newList);
return newList;
}
public List<T> GetEntry<T>()
{
object value;
if (_dictionaryOfLists.TryGetValue(typeof(T), out value))
{
return (List<T>)value;
}
return null;
}
public void RemoveEntry<T>()
{
_dictionaryOfLists.Remove(typeof(T));
}
}
I have a generic base class for value caching functionality.
public abstract class CachedValueProviderBase<T> : ICachedValueProvider<T> where T : class
{
private Cache Cache { set; get; }
protected string CacheKey { get; set; }
protected int CacheSpanInMinutes { get; set; }
private static readonly object _cacheLock = new object();
public T Values
{
get
{
T value = Cache[CacheKey] as T;
if (value == null)
{
lock (_cacheLock)
{
value = Cache[CacheKey] as T;
if (value == null)
{
value = InitializeCache();
}
}
}
return value;
}
}
protected CachedValueProviderBase()
{
Cache = HttpRuntime.Cache;
CacheSpanInMinutes = 15;
}
public T CacheValue(T value)
{
if (value != null)
{
lock (_cacheLock)
{
Cache.Insert(CacheKey, value, null, DateTime.UtcNow.AddMinutes(CacheSpanInMinutes),
Cache.NoSlidingExpiration);
}
}
return value;
}
private T InitializeCache()
{
T value = Initialize();
CacheValue(value);
return value;
}
protected abstract T Initialize();
}
I have several classes that make use of this base class and as long as the T is different it is fine. When two sub classes use the same T, string for example, they share the same cache lock object. What is the best way of implementing the logic in a base class but still giving each sub class it's own cache lock object?
Update
After the suggestions below I have updated my class:
public abstract class CachedValueProviderBase<T> : ICachedValueProvider<T> where T : class
{
private Cache Cache { set; get; }
protected string CacheKey { get; set; }
protected int CacheSpanInMinutes { get; set; }
private object _cacheLock = new object();
public T Values
{
get
{
T value = Cache[CacheKey] as T;
if (value == null)
{
lock (_cacheLock)
{
value = Cache[CacheKey] as T;
if (value == null)
{
value = InitializeCache();
}
}
}
return value;
}
}
protected CachedValueProviderBase()
{
Cache = HttpRuntime.Cache;
CacheSpanInMinutes = 15;
}
public T CacheValue(T value)
{
if (value != null)
{
Cache.Insert(CacheKey, value, null, DateTime.UtcNow.AddMinutes(CacheSpanInMinutes),
Cache.NoSlidingExpiration);
}
return value;
}
private T InitializeCache()
{
T value = Initialize();
CacheValue(value);
return value;
}
protected abstract T Initialize();
}
}
My sub classes are now singletons so I could get rid of the static cachelock object making it an instance variable.
I had to take a good look at your code, to find out if it was correct. Once I noticed your cache is a HttpRuntime.Cache, it made sense. The HttpRuntime.Cache is thread-safe. Otherwise you would have had several thread-safety problems. With your current, code I advice you to do the following:
private string CacheKey { get; set; }
protected CachedValueProviderBase(string cacheKey)
{
this.CacheKey = cacheKey + "_" + typeof(T).FullName;
}
By supplying the cacheKey as constructor argument and making the property private (or readonly would do), you prevent it from being changed by later on. By appending the type name to the key, you prevent cache conflicts since everybody is using the same cache.
One last note. The lock in the CacheValue method is redundant, since the Cache is thread-safe.
Well, just remove the static modifier on your cacheLock object.
That keyword forces the field to be shared between all instances of subclasses that share the same generic parameter type.
If you remove it, the cacheLock object will be private to each instance of a subclass, regardless of the generic parameter's type.
private static readonly object _cacheLock = new object();
Should be :
private readonly object _cacheLock = new object();
Hope that helps
I handled this by implementing an abstract method in my base class GetCacheLockObject().
protected abstract object GetCacheLockObject();
Each derived class then returns its own reference to the cache lock object:
private static readonly object _cacheLockObject = new Object();
protected override object GetCacheLockObject()
{
return _cacheLockObject;
}
Calls to lock in the shared base class caching code then reference this method rather than an object in the base class.