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.