Linfu dynamic proxy and Interface methods that return IEnumerable<object>

511 views Asked by At

I am using Linfu to generate a proxy object for an interface. Everything works fine except when calling a method that returns an IEnumerable<object> I get an error something like this:

Unable to cast object of type '< IEnumerableRpcCall >d__2' to type 'System.Collections.Generic.IEnumerable`1[System.String]'.

FYI: IEnumerableRpcCall is the name of the method inside the interceptor code that does yield return object rather than return object.

It seems the problem is that linfu is returning a pointer to the method rather than an IEnumerable. Has anyone found a workaround for this?

1

There are 1 answers

0
Franchesca On BEST ANSWER

The problem seems to be related to casting up from IEnumerable< object > to IEnumerable< string > (or whatever type). I solved it by wrapping my enumerator logic inside a custom class that implements IEnumerable<T>:

  public class MyEnumerator<T> : IEnumerable<T>, IEnumerable
  {
        // custom logic here
  }

and then in my interceptor code I use reflection to instantiate the correct generic type as specified in the InvocationInfo object:

  private class MyLinfuInterceptor : IInterceptor
  {
      public object Intercept(InvocationInfo info)
      {
            MethodInfo methodBeingRequested = info.TargetMethod;
            // enumerable return type
            if (methodBeingRequested.ReturnType.IsGenericType
               && methodBeingRequested.ReturnType.GetGenericTypeDefinition() == typeof(IEnumerable<>)
               && methodBeingRequested.ReturnType.GetGenericArguments().Length == 1)
            {
               Type constructedEnumerator = typeof(MyEnumerator<>).MakeGenericType(methodBeingRequested.ReturnType.GetGenericArguments());
               var result = Activator.CreateInstance(constructedEnumerator);

               return result;
            }

            // code to handle other return types here...
       }
   }

And now the proxy object for my interface no longer throws an invalid cast exception when I make method calls that return IEnumerable<>

(more on writing LinFu Dynamic Proxy interceptors here)