I’m trying to utilise the System.Runtime.Caching.MemoryCache class in .NET 4.0. I have a method that is generic so I can pass any type into the memory cache and get it back when invoked.
The method returns an object of type object which is an anonymous type with a field Value which contains the cached object.
My question is, how can I cast the object I’m getting back into its corresponding type?
Below is my code…
public static class ObjectCache
{
private static MemoryCache _cache = new MemoryCache("GetAllMakes");
public static object GetItem(string key)
{
return AddOrGetExisting(key, () => InitialiseItem(key));
}
private static T AddOrGetExisting<T>(string key, Func<T> valueFactory)
{
var newValue = new Lazy<T>(valueFactory);
var oldValue = _cache.AddOrGetExisting(key, newValue, new CacheItemPolicy()) as Lazy<T>;
try
{
return (oldValue ?? newValue).Value;
}
catch
{
_cache.Remove(key);
throw;
}
}
/// <summary>
/// How can i access Value and cast to type "List<IBrowseStockVehicle>"
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
private static object InitialiseItem(string key)
{
// SearchVehicleData.GetAllMakes(false) is of type List<IBrowseStockVehicle>
return new { Value = SearchVehicleData.GetAllMakes(false) };
}
}
and the unit test...
[TestMethod]
public void TestGetAllMakes_Cached()
{
dynamic ReturnObj = ObjectCache.GetItem("GetAllMakes");
// *********************************************
// cannot do this as tester is of type Object and doesnt have teh field Value
foreach(IBrowseStockVehicle item in ReturnObj.Value)
{
}
}
You can't do this! Anonymous types are anonymous from a high-level/semantic point of view (i.e. you can't cast to an unknown type, can you?), and they're internal and with a random name from a low level point of view. That is, they're inaccessible.
I can suggest you two approaches:
Convert the whole object to a dictionary and access its properties using keys. Some answers I did a long time ago should be useful on this case for simpler cases like yours: Mapping object to dictionary and vice versa and How to convert class into Dictionary<string,string>?
Dynamic objects to the rescue!
Dynamic objects to the rescue
In your question you said that you can't access a property of
object
, but you can implement a simpleDynamicObject
to access any object property dynamically:And use the whole wrapper as follows:
Conclusion
Store and retrieve your cached object wrapped with something like
DynamicWrapper
and it will work as you expect!Otherwise use dictionaries.
Or, like other answerers have already said, don't use anonymous type and store concrete types.