0

I want to creating and Aspect for caching. I need to know how can I create a cache key from a method call and insert it in cache with its return value. is there any solution out there available for THIS part. I don't need complete caching solution

Thanks

Ehsan
  • 1,662
  • 6
  • 28
  • 49

1 Answers1

0

I've previously used the RealProxy for this type of functionality. I've shown some examples in my blog post; Intercepting method invocations using RealProxy.

A quick example of a caching proxy, using the hash code of the method (to ensure that two different methods with same arguments are cached separately) and the arguments. Note that there's no handling of out-parameters, only the return value. (You would need to change the _cache to hold an object that contains both return value and output parameters if you want to change this.) Also, there's no form av thread safety with this implementation.

public class CachingProxy<T> : ProxyBase<T> where T : class {
    private readonly IDictionary<Int32, Object> _cache = new Dictionary<Int32, Object>();

    public CachingProxy(T instance)
        : base(instance) {
    }

    protected override IMethodReturnMessage InvokeMethodCall(IMethodCallMessage msg) {
        var cacheKey = GetMethodCallHashCode(msg);

        Object result;
        if (_cache.TryGetValue(cacheKey, out result))
            return new ReturnMessage(result, msg.Args, msg.ArgCount, msg.LogicalCallContext, msg);

        var returnMessage = base.InvokeMethodCall(msg);

        if (returnMessage.Exception == null)
            _cache[cacheKey] = returnMessage.ReturnValue;

        return returnMessage;
    }

    protected virtual Int32 GetMethodCallHashCode(IMethodCallMessage msg) {
        var hash = msg.MethodBase.GetHashCode();

        foreach(var arg in msg.InArgs) {
            var argHash = (arg != null) ? arg.GetHashCode() : 0;
            hash = ((hash << 5) + hash) ^ argHash;
        }

        return hash;
    }
}
sisve
  • 19,501
  • 3
  • 53
  • 95
  • I think you didn't get the problem, I need to know if there is a solution for creating a cache key (string) representing a method call and its return value. for example caching SomeMethod(param1, param2), but looking for general solution that is able to cache any method with any number of parameters – Ehsan Apr 09 '12 at 11:17
  • I've added an example CachingProxy, based on the ProxyBase class, that caches invocations. – sisve Apr 09 '12 at 14:01
  • Based on MSDN documentation GetHashCode method is not reliable for creating unique hash key, and if we say that we should implement this method for every Type, I think it is a bad practice too http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx line 3 of Remarks section – Ehsan Apr 09 '12 at 18:38
  • I'm looking for reliable implementation of GetMethodCallHashCode method in your snippet code, Thanks – Ehsan Apr 09 '12 at 18:42
  • You could rewrite that whole code snippet into actually using the parameters as a key, and iterate through all cached items and call Equals to verify that it's the same parameters. Something like an IDictionary>, and an IEqualityComparer which handles both GetHashCode and Equals. – sisve Apr 10 '12 at 05:47