public static void EmitProxyMethod(this ILGenerator ilGenerator, MethodInfo methodInfo,
                                           FieldBuilder _actors, FieldBuilder serviceProvider, FieldBuilder instance
                                           )
        {
            var returnType = methodInfo.ReturnType;
            var isAsync    = returnType == typeof(Task) || returnType.BaseType == typeof(Task);
            var funcType   = ExpressionExtension.CreateFuncType(isAsync ? returnType : typeof(object));

            var method     = ilGenerator.DeclareLocal(typeof(MethodInfo));
            var parameters = ilGenerator.DeclareLocal(typeof(object[]));
            var _delegate  = ilGenerator.DeclareLocal(typeof(Delegate));
            var _func      = ilGenerator.DeclareLocal(funcType);

            var paramTypes = methodInfo
                             .GetParameters()
                             // ReSharper disable once InconsistentNaming
                             .Select(_parameter => _parameter.ParameterType)
                             .ToArray();

            #region methodInfo
            ilGenerator.EmitMethod(methodInfo);
            ilGenerator.Emit(OpCodes.Stloc_0, method);
            #endregion

            #region args
            ilGenerator.AddLdcI4(paramTypes.Length);
            ilGenerator.Emit(OpCodes.Newarr, typeof(object));

            for (var j = 0; j < paramTypes.Length; j++)
            {
                ilGenerator.Emit(OpCodes.Dup);
                ilGenerator.AddLdcI4(j);
                ilGenerator.EmitLoadArg(j + 1);

                var parameterType = paramTypes[j];
                if (parameterType.GetTypeInfo().IsValueType || parameterType.IsGenericParameter)
                {
                    ilGenerator.Emit(OpCodes.Box, parameterType);
                }
                ilGenerator.Emit(OpCodes.Stelem_Ref);
            }

            ilGenerator.Emit(OpCodes.Stloc, parameters);
            #endregion

            #region Delegate
            ilGenerator.Emit(OpCodes.Ldtoken, isAsync ? returnType : typeof(object));
            ilGenerator.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle", new[] { typeof(RuntimeTypeHandle) }));
            ilGenerator.Emit(OpCodes.Call, typeof(ExpressionExtension).GetMethod("BuilderDelegate", new[] { typeof(Type) }));
            ilGenerator.Emit(OpCodes.Stloc, _delegate);
            #endregion

            #region Convert To Func
            ilGenerator.Emit(OpCodes.Ldloc, _delegate);
            ilGenerator.Emit(OpCodes.Castclass, funcType);
            ilGenerator.Emit(OpCodes.Stloc, _func);
            #endregion

            ilGenerator.Emit(OpCodes.Ldarg_0);
            ilGenerator.Emit(OpCodes.Ldfld, _actors);
            ilGenerator.Emit(OpCodes.Ldloc, _func);
            ilGenerator.Emit(OpCodes.Ldarg_0);
            ilGenerator.Emit(OpCodes.Ldfld, serviceProvider);
            ilGenerator.Emit(OpCodes.Ldarg_0);
            ilGenerator.Emit(OpCodes.Ldfld, instance);
            ilGenerator.Emit(OpCodes.Ldloc, method);
            ilGenerator.Emit(OpCodes.Ldloc, parameters);

            #region AopContext
            ilGenerator.Emit(OpCodes.Newobj, typeof(AopContext).GetConstructor(new[]
            {
                typeof(IServiceProvider),
                typeof(object),
                typeof(MethodInfo),
                typeof(object[])
            }));
            #endregion

            if (isAsync)
            {
                if (returnType.IsGenericType)
                {
                    var typeInfo = returnType.GetTypeInfo();
                    var genericTypeDefinition = typeInfo.GetGenericArguments().Single();

                    ilGenerator.Emit(OpCodes.Callvirt, typeof(DefaultAopActors).GetMethod("ExecuteAsync").MakeGenericMethod(genericTypeDefinition));
                }
                else
                {
                    ilGenerator.Emit(OpCodes.Callvirt, typeof(DefaultAopActors).GetMethod("InvokeAsync"));
                }
            }
            else
            {
                //_actor.Execute(_invoke,context);
                ilGenerator.Emit(OpCodes.Callvirt, typeof(DefaultAopActors).GetMethod("Execute", new[]
                {
                    funcType,
                    typeof(AopContext)
                }));
            }

            if (returnType == typeof(void))
            {
                ilGenerator.Emit(OpCodes.Pop);
            }

            if (returnType != typeof(void) && returnType.IsValueType)
            {
                ilGenerator.Emit(OpCodes.Unbox_Any, returnType);
            }

            if (!isAsync && returnType.IsGenericType)
            {
                ilGenerator.Emit(OpCodes.Castclass, returnType);
            }

            ilGenerator.Emit(OpCodes.Ret);
        }