/// <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 var delegateType, out var invokeMethod);
            int index;

            lock (_dynamicMethods)
            {
                _dynamicMethods.Add(dynamicMethod);
                index = _dynamicMethods.Count - 1;
            }

            // We fill the DelegateCache<> for that custom type with the delegate instance
            var fillDelegateMethodInfo = typeof(Elastic.Apm.Profiler.Managed.DuckTyping.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);
        }