I have an array which stores a dictionary of Types:
//The dictionary:
Dictionary<CacheKey,Type> TypeLookup;
//This is the enum:
public enum CacheKey
{
UserProfile,
CustomerQuickSearch,
CommissionConfiguration
}
I would like to use this Dictionary to declare a variable of type T
//instead of
T myvar;
//I want to dynamically declare myvar as:
//1)get the type for the cacheKey from the dictionary:
Type type = TypeLookup[cacheKey];
//2)declare myvar as the corresponding Type:
type myvar;
The background is that I am building a Distributed Caching infrastructure. I have a great little CachingProvider that allows you to update an item in the cache.
I would like to expose this method as a webservice so that all the servers in my farm can have their cache updated. But I would like to have only one method exposed as a webservice which then updates the corresponding item in cache.
This is the method I'm trying to expose:
public static void UpdateCacheEntryItem<T>(CacheKey cacheKey, int id)
{
//look up the cacheEntry in cache which is a dictionary.
Dictionary<int, T> cacheEntry = (Dictionary<int, T>) CacheRef[cacheKey.ToString()];
//call the corresponding method which knows how to hydrate that item and pass in the id.
cacheEntry[id] = (T)HydrateCacheEntryItemMethods[cacheKey].Invoke(id);
}
Things I've tried:
1) I tried exposing the method directly as a WCF service but of course that doesn't work because of the on the method.
2) I tried casting the Dictionary which would be find because I don't need to do anthing with the return value, I just need to update the item in cache. But that didn't work either. Error that I get: Unable to cast object of type 'System.Collections.Generic.Dictionary2[System.Int32,CachingPrototype.CustomerQuickSearch]' to type 'System.Collections.Generic.Dictionary
2[System.Int32,System.Object]'.
Your comments were very helpful and helped me to answer my question. The solution I came up with is to simply wrap my WCF service method in a switch statement so that I could call the UpdateCacheEntryItem method with the correct type of T. Since there is no way to convert from Type to the generic T operator, this is the only option. Since I don't have that many types in Cache, this works pretty well. (The other solution would be to use an interface as stated below but that would not be as strongly typed as I would like.)
[OperationContract]
public void UpdateCacheEntryItem(CacheKey cacheKey, int id)
{
switch (cacheKey)
{
case CacheKey.UserProfile:
CacheProvider.UpdateCacheEntryItem<UserProfile>(cacheKey, id);
break;
case CacheKey.CommissionConfig:
CacheProvider.UpdateCacheEntryItem<CommissionConfig>(cacheKey, id);
break;
case CacheKey.CustomerQuickSearch:
CacheProvider.UpdateCacheEntryItem<CustomerQuickSearch>(cacheKey, id);
break;
default:
throw new Exception("Invalid CacheKey");
}
Thanks everyone for your help, you are brilliant!