/// <summary> /// Write a DynamicMethod call by creating and injecting a custom delegate in the proxyType /// </summary> /// <param name="il">LazyILGenerator instance</param> /// <param name="dynamicMethod">Dynamic method to get called</param> /// <param name="proxyType">ProxyType builder</param> internal static void WriteDynamicMethodCall(this LazyILGenerator il, DynamicMethod dynamicMethod, TypeBuilder proxyType) { // We create a custom delegate inside the module builder CreateDelegateTypeFor(proxyType, dynamicMethod, out Type delegateType, out MethodInfo invokeMethod); int index; lock (_dynamicMethods) { _dynamicMethods.Add(dynamicMethod); index = _dynamicMethods.Count - 1; } // We fill the DelegateCache<> for that custom type with the delegate instance MethodInfo fillDelegateMethodInfo = typeof(DuckType.DelegateCache <>).MakeGenericType(delegateType).GetMethod("FillDelegate", BindingFlags.NonPublic | BindingFlags.Static); fillDelegateMethodInfo.Invoke(null, new object[] { index }); // We get the delegate instance and load it in to the stack before the parameters (at the begining of the IL body) il.SetOffset(0); il.EmitCall(OpCodes.Call, typeof(DuckType.DelegateCache <>).MakeGenericType(delegateType).GetMethod("GetDelegate"), null); il.ResetOffset(); // We emit the call to the delegate invoke method. il.EmitCall(OpCodes.Callvirt, invokeMethod, null); }