I am trying to cache my entities returned from repositories. I am intercepting calls to repository methods, so that I can check if the requested data exist in cache. But, since I am intercepting the method call, I can't obtain the real entity type, as you may guess I get an EF proxy type. So when I put it to cache, I am not putting the real entity, instead I am putting a subclass of it.
As I recall Nhibernate has some utility to initialize proxy immediately. Can we do it in EF 6? How can I get the underlying entity in here?
Here is some of my code to clarify my need. I am using Castle Interceptors by the way.
public class CacheInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
if (IsReturnTypeCacheable(invocation.Method.ReturnType))
{
string cacheKey = this.CreateCacheKey(invocation.Method.Name, invocation.Arguments);
object returnValue = this.GetFromCache<object>(cacheKey);
if (returnValue != null)
{
invocation.ReturnValue = returnValue;
return;
}
else
{
invocation.Proceed();
object actualValue = invocation.ReturnValue;
Type proxyType = invocation.ReturnValue.GetType();
Type pocoType = proxyType.BaseType;
var dataInstance = Activator.CreateInstance(pocoType);
dataInstance = invocation.ReturnValue;
this.PutToCache(cacheKey, dataInstance);// This puts the proxy type to cache, not underlying POCO...
}
}
else
{
invocation.Proceed();
}
}
private bool IsReturnTypeCacheable(Type type)
{
//some custom checks
}
public T GetFromCache<T>(string cacheKey) where T : class
{
IRedisNativeClient redisClient = new RedisNativeClient("myredis");
byte[] obj = redisClient.Get(cacheKey);
if (obj == null) return null;
return Serializer.Deserialize<T>(obj);
}
public void PutToCache(string cacheKey, object value)
{
if (value == null) return;
IRedisNativeClient redisClient = new RedisNativeClient("myredis");
redisClient.Set(cacheKey, Serializer.Serialize(value));
}
public string CreateCacheKey(string method, object[] arguments)
{
//creates cache key
}
}