jeudi 30 juillet 2015

Mono Cecil get delegate method argument

I have a very simple assembly below. I'm trying to use Mono.Cecil to reflect over it to find the parameter passed to all calls to CallApiAsync. When I isolate the MethodReference for the call I cannot seem to get the parameter x.GetResponse(new SomeRequestType()), I just get the delegate definition ApiMethodAsync<T, TResult>. I've drawn a blank on this, any help appreciated.

public class ApiWrapper
{
 public delegate Task<TResult> ApiMethodAsync<T, TResult>(T api);

 public virtual async Task<SomeResponseType> MakeSomeRequestToApi() 
 {
    return await CallApiAsync<ISomeApi, SomeResponseType>(x => x.GetResponse(new SomeRequestType()));
 }

 public virtual async Task<TResult> CallApiAsync<T, TResult>(ApiMethodAsync<T, TResult> apiMethod) where TResult : new()
 {
    return await Task.FromResult(new TResult());
 }
}

public interface ISomeApi
{
    Task<SomeResponseType> GetResponse(SomeRequestType request);
}

public class SomeResponseType { }
public class SomeRequestType { }

Below is the Mono Cecil code I am using to identify calls to CallApiAsync

var moduleDefinition = ModuleDefinition.ReadModule("SimpleAssembly.dll");

var targetClass = moduleDefinition.Types.Where(t => t.FullName.Contains("ApiWrapper")).Single();

            var nestedMethodInstructions = targetClass.NestedTypes
                                                      .SelectMany(p => p.Methods)
                                                      .Where(m => m.HasBody)
                                                      .SelectMany(t => t.Body.Instructions).ToList();

            foreach (var instr in nestedMethodInstructions)
            {
                if (instr.Operand != null)
                {
                    var methodRef = instr.Operand as MethodReference;

                    if (methodRef != null && methodRef.FullName.Contains("CallApiAsync"))
                    {
                        // Get the full delegate parameter, ie  GetResponse(new SomeRequestType())
                    }
                }
            }





Aucun commentaire:

Enregistrer un commentaire