I try to intercept a method through a proxy class and get a TargetException "Object does not match target type". I find this to be similar to what a structure like PostSharp does, but I want to see if I can do it myself as an exercise, at least.
The goal in this case is to call the method using Diagnostics.Stopwatch by transferring it to a new delegate. However, this is a bit compared to my head.
Here is the delegate that wraps the proxy method:
public static Func<Object> Time(this MethodInfo target, object parent, object[] parameters, Action<string> logger) { return delegate { Stopwatch s = new Stopwatch(); s.Start(); object value = target.Invoke(parent, parameters); s.Stop(); logger("Elapsed ms for function '" + target.Name + "' = " + s.ElapsedMilliseconds.ToString()); return value; }; }
And here is the method that performs the interception, essentially creating a new instance of MethodInfo, which describes the new delegate created here, which is based on whether the method has a specific attribute indicating that it should be synchronized:
public class FunctionInterceptor { public MethodInfo Intercept(Object proxy, MethodInfo method, Object[] args) { return new Func<Object>(() => { var data = method.GetCustomAttributes(typeof(TimeAttribute), true); object result = default(object); foreach (object d in data) { if (d.GetType() == typeof(TimeAttribute))
Now it seems to me that I should be able to call the delegate that describes this MethodInfo object:
var interceptor = new FunctionInterceptor(); retVal = interceptor.Intercept(proxy, method, parameters).Invoke(interceptor, parameters);
But I get an error. The object does not match the type of target. I looked at an instance of MethodInfo, and DeclaringType is a FunctionInterceptor, that is, I have to pass an instance of the interceptor as described above. I donβt know what the problem is.
If I do this, it works fine (just calling MethodInfo without wrapping it):
retVal = method.Invoke( obj, parameters );
Where obj is an instance declaring the method in question, one that is decorated with the [Time] attribute.
Thanks.