Hey Camden,

In:

    var genericArg = method.ReturnType.Resolve();
    var proxyReturnRefClosed = new GenericInstanceMethod(proxyReturnRefOpen
);
    proxyReturnRefClosed.GenericArguments.Add(genericArg);

Why do you Resolve the return type? I imagine you want to return exactly
the type of method.ReturnType, why don't you use that directly?

Jb

On Mon, Oct 2, 2017 at 11:41 AM, Camden Reslink <[email protected]>
wrote:

> Hello,
>
> I'm using version 0.9.6.4 consumed as a NuGet package from nuget.org.
>
> I'm trying to inject a call to a static method, which intercepts values
> that would have been returned, and logs/traces/manipulates them in some way
> and then returns them. An example of an intercepting method could look like
> this:
> public static T1 ReturnProxy<T1>(T1 value)
> {
>     // Do something useful with value, like logging it.
>     var timestamp = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff",
>                                     CultureInfo.InvariantCulture);
>     StackTrace stackTrace = new StackTrace();
>     var callingMethod = stackTrace.GetFrame(1).GetMethod();
>     File.AppendAllLines(@"C:\temp\test_app.txt", new string[] { timestamp
> + ", " + callingMethod.Name + ", " + Newtonsoft.Json.JsonConvert.Se
> rializeObject(value) });
>
>     // Now return it just like the calling method would have without this
> method intercepting it
>     return value;
> }
>
>
> And here is what a before/after would look like for injecting the
> instructions into the calling method:
> // This method is in the assembly being injected into
>
> //BEFORE
> public T2 MethodWithAGenericParameter<T2>(int someVariable)
> {
>     T2 obj = (T2)Activator.CreateInstance(typeof(T2));
>     obj.GetType().GetProperty("MyProperty").SetValue(obj, someVariable);
>     return obj;
> }
>
> //AFTER
> public T2 MethodWithAGenericParameter<T2>(int someVariable)
> {
>     T2 obj = (T2)Activator.CreateInstance(typeof(T2));
>     obj.GetType().GetProperty("MyProperty").SetValue(obj, someVariable);
>     return Injector.ReturnProxy<T2>(obj);
> }
>
>
> In the case where the return type of the calling method is not generic,
> the following code is working correctly to inject the call instructions
> into the methods:
> public static void InjectReturnProxy(MethodDefinition method)
> {
>     var injectorModuleDef = ModuleDefinition.ReadModule(typeof(Injector).
> Module.FullyQualifiedName);
>     var proxyReturnRefOpen = injectorModuleDef.GetType(typeof(Injector).
> FullName).Methods
>         .First(m => m.FullName == "T TestInjector.Injector::
> ReturnProxy(T)");
>     ILProcessor processor = method.Body.GetILProcessor();
>     Instruction proxyReturnInstruction = null;
>
>     var genericArg = method.ReturnType.Resolve();
>     var proxyReturnRefClosed = new GenericInstanceMethod(proxyRet
> urnRefOpen);
>     proxyReturnRefClosed.GenericArguments.Add(genericArg);
>     proxyReturnInstruction = processor.Create(OpCodes.Call, method.Module.
> Import(proxyReturnRefClosed));
>
>     var returnInstructions = method.Body.Instructions
>             .Where(i => i.OpCode.Name == "ret").ToArray();
>
>     method.Body.OptimizeMacros();
>     for (var i = 0; i < returnInstructions.Length; i++)
>     {
>         var instruction = returnInstructions[i];
>         processor.InsertBefore(instruction, proxyReturnInstruction);
>     }
>     method.Body.SimplifyMacros();
> }
>
> However, when the return type of the calling method is generic, like the
> MethodWithAGenericParameter example above, I can't seem to get the
> correct return type to pass as a generic type argument to the ReturnProxy<
> T1> static method. The call to method.ReturnType.Resolve() gives a value
> of null in that case, and the type of method.ReturnType is
> Mono.Cecil.GenericParameter. I also see problems with a return type of a
> generic array (like T[]). I haven't tried to resolve when the return type
> of the calling method is a generic type parameter at the class level
> instead of the method level, but I suspect I'll have similar issues in that
> case. Any thoughts on how to perform the above injection of a method call
> passing in as the generic argument the generic parameter of the parent
> method? Thanks for any help that could be provided!
>
> --
> --
> --
> mono-cecil
> ---
> You received this message because you are subscribed to the Google Groups
> "mono-cecil" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> For more options, visit https://groups.google.com/d/optout.
>

-- 
-- 
--
mono-cecil
--- 
You received this message because you are subscribed to the Google Groups 
"mono-cecil" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to