예제 #1
0
            /// <summary>
            /// 创建 TCP 客户端
            /// </summary>
            /// <param name="type"></param>
            /// <param name="attribute"></param>
            /// <param name="methods"></param>
            /// <param name="getCommandMethod"></param>
            /// <returns></returns>
            internal Type Build(Type type, TcpServer.ServerBaseAttribute attribute, Method <attributeType, methodAttributeType, serverSocketType>[] methods, MethodInfo getCommandMethod)
            {
                TypeBuilder typeBuilder = AutoCSer.Emit.Builder.Module.Builder.DefineType(Metadata.ClientTypeName + ".Emit." + type.FullName, TypeAttributes.Class | TypeAttributes.Sealed, Metadata.MethodClientType, new Type[] { type });

                typeBuilder.DefineDefaultConstructor(MethodAttributes.Public);

                ConstructorBuilder staticConstructorBuilder   = typeBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, null);
                ILGenerator        staticConstructorGenerator = staticConstructorBuilder.GetILGenerator();

                Commands = new TcpServer.CommandInfoBase[methods.Length];
                int parameterIndex;

                foreach (Method <attributeType, methodAttributeType, serverSocketType> nextMethod in methods)
                {
                    if (nextMethod != null)
                    {
                        Method <attributeType, methodAttributeType, serverSocketType> method = nextMethod;
METHOD:
                        FieldBuilder commandInfoFieldBuilder;
                        if (method.Attribute.IsExpired)
                        {
                            commandInfoFieldBuilder = null;
                        }
                        else
                        {
                            commandInfoFieldBuilder = typeBuilder.DefineField("_c" + method.Attribute.CommandIdentity.toString(), typeof(TcpServer.CommandInfoBase), FieldAttributes.Private | FieldAttributes.InitOnly | FieldAttributes.Static);
                            TcpServer.CommandInfoBase commandInfo = new TcpServer.CommandInfoBase {
                                Command = method.Attribute.CommandIdentity + TcpServer.Server.CommandStartIndex, IsVerifyMethod = method.Attribute.IsVerifyMethod
                            };
                            Commands[method.Attribute.CommandIdentity] = commandInfo;
                            if (method.IsJsonSerialize)
                            {
                                commandInfo.CommandFlags = TcpServer.CommandFlags.JsonSerialize;
                            }
                            if (method.ParameterType != null)
                            {
                                commandInfo.InputParameterIndex = method.ParameterType.Index;
                                if (attribute.IsSimpleSerialize)
                                {
                                    commandInfo.IsSimpleSerializeInputParamter = method.ParameterType.IsSimpleSerialize;
                                }
                            }
                            if (attribute.IsSimpleSerialize && method.OutputParameterType != null)
                            {
                                commandInfo.IsSimpleSerializeOutputParamter = method.OutputParameterType.IsSimpleSerialize && SimpleSerialize.Serializer.IsType(method.ReturnType);
                            }
                            #region private static readonly AutoCSer.Net.TcpServer.CommandInfoBase @MethodIdentityCommand = AutoCSer.Net.TcpInternalSimpleServer.Emit.Client<interfaceType>.commands[method.Attribute.CommandIdentity];
                            staticConstructorGenerator.int32(method.Attribute.CommandIdentity);
                            staticConstructorGenerator.call(getCommandMethod);
                            staticConstructorGenerator.Emit(OpCodes.Stsfld, commandInfoFieldBuilder);
                            #endregion
                        }
                        if (method.PropertyInfo == null)
                        {
                            ParameterInfo[] parameters    = method.MethodInfo.GetParameters();
                            MethodBuilder   methodBuilder = typeBuilder.DefineMethod(method.MethodInfo.Name, MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final, method.MethodInfo.ReturnType, parameters.getArray(parameter => parameter.ParameterType));
                            typeBuilder.DefineMethodOverride(methodBuilder, method.MethodInfo);
                            ILGenerator methodGenerator = methodBuilder.GetILGenerator();
                            if (method.Attribute.IsExpired)
                            {
                                if (method.ReturnValueType == null)
                                {
                                    #region throw new Exception(AutoCSer.Net.TcpServer.ReturnType.VersionExpired.ToString());
                                    methodGenerator.throwString(AutoCSer.Net.TcpServer.ReturnType.VersionExpired.ToString());
                                    #endregion
                                }
                                else
                                {
                                    #region @ParameterName = default(@ParameterType.FullName);
                                    parameterIndex = 0;
                                    foreach (ParameterInfo parameter in parameters)
                                    {
                                        ++parameterIndex;
                                        if (parameter.IsOut)
                                        {
                                            methodGenerator.outParameterDefault(parameter, parameterIndex, method.Attribute.IsInitobj);
                                        }
                                    }
                                    #endregion
                                    #region return new AutoCSer.Net.TcpServer.ReturnValue<@MethodReturnType.FullName> { Type = AutoCSer.Net.TcpServer.ReturnType.VersionExpired };
                                    LocalBuilder returnReturnValueLocalBuilder = methodGenerator.DeclareLocal(method.ReturnValueType);
                                    if (method.ReturnType != typeof(void) && (method.Attribute.IsInitobj || method.ReturnType.isInitobj()))
                                    {
                                        methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Initobj, method.ReturnValueType);
                                    }
                                    methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder);
                                    methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.VersionExpired);
                                    methodGenerator.Emit(OpCodes.Stfld, method.ReturnType == typeof(void) ? TcpServer.Emit.ClientMetadata.ReturnValueTypeField : method.ReturnValueType.GetField(TcpServer.Emit.ClientMetadata.ReturnValueTypeField.Name, BindingFlags.Instance | BindingFlags.Public));
                                    methodGenerator.Emit(OpCodes.Ldloc_S, returnReturnValueLocalBuilder);
                                    methodGenerator.Emit(OpCodes.Ret);
                                    #endregion
                                }
                            }
                            else
                            {
                                Label clientExceptionLabel = methodGenerator.DefineLabel();
                                #region if (_isDisposed_ == 0)
                                methodGenerator.Emit(OpCodes.Ldarg_0);
                                methodGenerator.call(TcpSimpleServer.Emit.ClientMetadata.MethodClientGetIsDisposedMethod);
                                methodGenerator.Emit(method.ParameterType == null && method.OutputParameterType == null ? OpCodes.Brtrue_S : OpCodes.Brtrue, clientExceptionLabel);
                                #endregion
                                LocalBuilder inputParameterLocalBuilder;
                                if (method.ParameterType == null)
                                {
                                    inputParameterLocalBuilder = null;
                                }
                                else
                                {
                                    #region TcpInternalSimpleServer.@InputParameterTypeName _inputParameter_ = new TcpInternalSimpleServer.@InputParameterTypeName { @ParameterName = @ParameterName };
                                    inputParameterLocalBuilder = methodGenerator.DeclareLocal(method.ParameterType.Type);
                                    LocalBuilder newInputParameterLocalBuilder = methodGenerator.DeclareLocal(method.ParameterType.Type);
                                    if (method.Attribute.IsInitobj || method.ParameterType.IsInitobj)
                                    {
                                        methodGenerator.Emit(OpCodes.Ldloca_S, newInputParameterLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Initobj, method.ParameterType.Type);
                                    }
                                    parameterIndex = 0;
                                    foreach (ParameterInfo parameter in parameters)
                                    {
                                        ++parameterIndex;
                                        if (SimpleParameterType.IsInputParameter(parameter))
                                        {
                                            methodGenerator.parameterToStructField(parameter, parameterIndex, newInputParameterLocalBuilder, method.ParameterType.GetField(parameter.Name));
                                        }
                                    }
                                    methodGenerator.Emit(OpCodes.Ldloc_S, newInputParameterLocalBuilder);
                                    methodGenerator.Emit(OpCodes.Stloc_S, inputParameterLocalBuilder);
                                    #endregion
                                }
                                if (method.OutputParameterType == null)
                                {
                                    #region AutoCSer.Net.TcpServer.ReturnType _returnType_ = _TcpClient_.Call(@MethodIdentityCommand, ref _inputParameter_);
                                    LocalBuilder returnTypeLocalBuilder = methodGenerator.DeclareLocal(typeof(AutoCSer.Net.TcpServer.ReturnType));
                                    methodGenerator.Emit(OpCodes.Ldarg_0);
                                    methodGenerator.call(Metadata.MethodClientGetTcpClientMethod);
                                    methodGenerator.Emit(OpCodes.Ldsfld, commandInfoFieldBuilder);
                                    if (method.ParameterType == null)
                                    {
                                        methodGenerator.call(Metadata.ClientCallMethod);
                                    }
                                    else
                                    {
                                        methodGenerator.Emit(OpCodes.Ldloca_S, inputParameterLocalBuilder);
                                        //methodGenerator.call(Metadata.ClientCallInputMethod.MakeGenericMethod(method.ParameterType.Type));
                                        methodGenerator.call(Metadata.GetParameterGenericType(method.ParameterType.Type).ClientCallMethod);
                                    }
                                    methodGenerator.Emit(OpCodes.Stloc_S, returnTypeLocalBuilder);
                                    #endregion
                                    if (method.ReturnValueType == null)
                                    {
                                        Label throwReturnTypeLabel = methodGenerator.DefineLabel();
                                        #region if (_returnType_ == AutoCSer.Net.TcpServer.ReturnType.Success) return;
                                        methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder);
                                        methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.Success);
                                        methodGenerator.Emit(OpCodes.Bne_Un_S, throwReturnTypeLabel);
                                        methodGenerator.Emit(OpCodes.Ret);
                                        #endregion
                                        methodGenerator.MarkLabel(throwReturnTypeLabel);
                                        #region throw new Exception(AutoCSer.Net.TcpInternalServer.Emit.Client.ReturnTypeStrings[(byte)_returnType_]);
                                        methodGenerator.Emit(OpCodes.Ldsfld, TcpServer.Emit.ClientMetadata.ReturnTypeStringsField);
                                        methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Ldelem_Ref);
                                        methodGenerator.call(AutoCSer.Extensions.EmitGenerator.NewExceptionStringMethodInfo);
                                        methodGenerator.Emit(OpCodes.Throw);
                                        #endregion
                                    }
                                    else
                                    {
                                        #region return new AutoCSer.Net.TcpServer.ReturnValue { Type = _returnType_ };
                                        LocalBuilder returnReturnValueLocalBuilder = methodGenerator.DeclareLocal(method.ReturnValueType);
                                        //methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder);
                                        //methodGenerator.Emit(OpCodes.Initobj, method.ReturnValueType);
                                        methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Stfld, TcpServer.Emit.ClientMetadata.ReturnValueTypeField);
                                        methodGenerator.Emit(OpCodes.Ldloc_S, returnReturnValueLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Ret);
                                        #endregion
                                    }
                                }
                                else
                                {
                                    #region TcpInternalSimpleServer.@OutputParameterTypeName _outputParameter_ = new TcpInternalSimpleServer.@OutputParameterTypeName { @ParameterName = @ParameterName };
                                    LocalBuilder outputParameterLocalBuilder = methodGenerator.DeclareLocal(method.OutputParameterType.Type);
                                    if (method.Attribute.IsInitobj || method.OutputParameterType.IsInitobj)
                                    {
                                        methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Initobj, method.OutputParameterType.Type);
                                    }
                                    parameterIndex = 0;
                                    foreach (ParameterInfo parameter in parameters)
                                    {
                                        ++parameterIndex;
                                        if (parameter.ParameterType.IsByRef)
                                        {
                                            methodGenerator.parameterToStructField(parameter, parameterIndex, outputParameterLocalBuilder, method.OutputParameterType.GetField(parameter.Name));
                                        }
                                    }
                                    //if (method.ReturnInputParameter != null)
                                    //{
                                    //}
                                    #endregion
                                    #region AutoCSer.Net.TcpServer.ReturnType _returnType_ = _TcpClient_.Get<TcpInternalSimpleServer.@InputParameterTypeName, TcpInternalSimpleServer.@OutputParameterTypeName>(@MethodIdentityCommand, ref _inputParameter_, ref _outputParameter_);
                                    LocalBuilder returnTypeLocalBuilder = methodGenerator.DeclareLocal(typeof(AutoCSer.Net.TcpServer.ReturnType));
                                    methodGenerator.Emit(OpCodes.Ldarg_0);
                                    methodGenerator.call(Metadata.MethodClientGetTcpClientMethod);
                                    methodGenerator.Emit(OpCodes.Ldsfld, commandInfoFieldBuilder);
                                    if (method.ParameterType == null)
                                    {
                                        methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder);
                                        //methodGenerator.call(Metadata.ClientGetMethod.MakeGenericMethod(method.OutputParameterType.Type));
                                        methodGenerator.call(Metadata.GetParameterGenericType(method.OutputParameterType.Type).ClientGetMethod);
                                    }
                                    else
                                    {
                                        methodGenerator.Emit(OpCodes.Ldloca_S, inputParameterLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder);
                                        //methodGenerator.call(Metadata.ClientGetInputMethod.MakeGenericMethod(method.ParameterType.Type, method.OutputParameterType.Type));
                                        methodGenerator.call(Metadata.GetParameterGenericType2(method.ParameterType.Type, method.OutputParameterType.Type).ClientGetMethod);
                                    }
                                    methodGenerator.Emit(OpCodes.Stloc_S, returnTypeLocalBuilder);
                                    #endregion
                                    if (method.ReturnValueType == null)
                                    {
                                        Label throwReturnTypeLabel = methodGenerator.DefineLabel();
                                        #region if (_returnType_ == AutoCSer.Net.TcpServer.ReturnType.Success)
                                        methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder);
                                        methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.Success);
                                        methodGenerator.Emit(OpCodes.Bne_Un, throwReturnTypeLabel);
                                        #endregion
                                        #region @ParameterName = _outputParameter_.@ParameterName;
                                        parameterIndex = 0;
                                        foreach (ParameterInfo parameter in parameters)
                                        {
                                            ++parameterIndex;
                                            if (parameter.ParameterType.IsByRef)
                                            {
                                                methodGenerator.outParameterFromValueField(parameter, parameterIndex, outputParameterLocalBuilder, method.OutputParameterType.GetField(parameter.Name));
                                            }
                                        }
                                        #endregion
                                        if (method.ReturnType == typeof(void))
                                        {
                                            #region return;
                                            methodGenerator.Emit(OpCodes.Ret);
                                            #endregion
                                        }
                                        else
                                        {
                                            #region return _outputParameter_.Ret;
                                            methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder);
                                            methodGenerator.Emit(OpCodes.Ldfld, method.OutputParameterType.GetField(TcpServer.ReturnValue.RetParameterName));
                                            //methodGenerator.Emit(OpCodes.Stloc_S, returnValueLocalBuilder);
                                            //methodGenerator.Emit(OpCodes.Ldloc_S, returnValueLocalBuilder);
                                            methodGenerator.Emit(OpCodes.Ret);
                                            #endregion
                                        }
                                        methodGenerator.MarkLabel(throwReturnTypeLabel);
                                        #region throw new Exception(AutoCSer.Net.TcpServer.Emit.Client.ReturnTypeStrings[(byte)_returnType_]);
                                        methodGenerator.Emit(OpCodes.Ldsfld, TcpServer.Emit.ClientMetadata.ReturnTypeStringsField);
                                        methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Ldelem_Ref);
                                        methodGenerator.call(AutoCSer.Extensions.EmitGenerator.NewExceptionStringMethodInfo);
                                        methodGenerator.Emit(OpCodes.Throw);
                                        #endregion
                                    }
                                    else
                                    {
                                        #region @ParameterName = _outputParameter_.@ParameterName;
                                        parameterIndex = 0;
                                        foreach (ParameterInfo parameter in parameters)
                                        {
                                            ++parameterIndex;
                                            if (parameter.ParameterType.IsByRef)
                                            {
                                                methodGenerator.outParameterFromValueField(parameter, parameterIndex, outputParameterLocalBuilder, method.OutputParameterType.GetField(parameter.Name));
                                            }
                                        }
                                        #endregion
                                        #region return new AutoCSer.Net.TcpServer.ReturnValue<@MethodReturnType.FullName> { Type = _returnType_, Value = _outputParameter_.Return };
                                        LocalBuilder returnReturnValueLocalBuilder = methodGenerator.DeclareLocal(method.ReturnValueType);
                                        if (method.ReturnType == typeof(void))
                                        {
                                            methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder);
                                            methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder);
                                            methodGenerator.Emit(OpCodes.Stfld, TcpServer.Emit.ClientMetadata.ReturnValueTypeField);
                                        }
                                        else
                                        {
                                            if (method.Attribute.IsInitobj || method.ReturnType.isInitobj())
                                            {
                                                methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder);
                                                methodGenerator.Emit(OpCodes.Initobj, method.ReturnValueType);
                                            }
                                            methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder);
                                            methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder);
                                            methodGenerator.Emit(OpCodes.Stfld, method.ReturnValueType.GetField(TcpServer.Emit.ClientMetadata.ReturnValueTypeField.Name, BindingFlags.Instance | BindingFlags.Public));
                                            methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder);
                                            methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder);
                                            methodGenerator.Emit(OpCodes.Ldfld, method.OutputParameterType.GetField(TcpServer.ReturnValue.RetParameterName));
                                            methodGenerator.Emit(OpCodes.Stfld, method.ReturnValueType.GetField("Value", BindingFlags.Instance | BindingFlags.Public));
                                        }
                                        methodGenerator.Emit(OpCodes.Ldloc_S, returnReturnValueLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Ret);
                                        #endregion
                                    }
                                }
                                methodGenerator.MarkLabel(clientExceptionLabel);
                                if (method.ReturnValueType == null)
                                {
                                    #region throw new Exception(AutoCSer.Net.TcpServer.ReturnType.ClientException.ToString());
                                    methodGenerator.throwString(AutoCSer.Net.TcpServer.ReturnType.ClientException.ToString());
                                    #endregion
                                }
                                else
                                {
                                    #region @ParameterName = default(@ParameterType.FullName);
                                    parameterIndex = 0;
                                    foreach (ParameterInfo parameter in parameters)
                                    {
                                        ++parameterIndex;
                                        if (parameter.IsOut)
                                        {
                                            methodGenerator.outParameterDefault(parameter, parameterIndex, method.Attribute.IsInitobj);
                                        }
                                    }
                                    #endregion
                                    #region return new AutoCSer.Net.TcpServer.ReturnValue<@MethodReturnType.FullName> { Type = AutoCSer.Net.TcpServer.ReturnType.ClientException };
                                    LocalBuilder returnReturnValueLocalBuilder = methodGenerator.DeclareLocal(method.ReturnValueType);
                                    if (method.ReturnType != typeof(void) && method.ReturnType.isInitobj())
                                    {
                                        methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Initobj, method.ReturnValueType);
                                    }
                                    methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder);
                                    methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.ClientException);
                                    methodGenerator.Emit(OpCodes.Stfld, method.ReturnType == typeof(void) ? TcpServer.Emit.ClientMetadata.ReturnValueTypeField : method.ReturnValueType.GetField(TcpServer.Emit.ClientMetadata.ReturnValueTypeField.Name, BindingFlags.Instance | BindingFlags.Public));
                                    methodGenerator.Emit(OpCodes.Ldloc_S, returnReturnValueLocalBuilder);
                                    methodGenerator.Emit(OpCodes.Ret);
                                    #endregion
                                }
                            }
                        }
                        else if (method.IsPropertySetMethod)
                        {
                            if (method.PropertyBuilder != null || method.PropertyGetMethod == null)
                            {
                                ParameterInfo[] parameters      = method.MethodInfo.GetParameters();
                                PropertyBuilder propertyBuilder = method.PropertyBuilder ?? typeBuilder.DefineProperty(method.PropertyInfo.Name, PropertyAttributes.HasDefault, parameters[parameters.Length - 1].ParameterType, new LeftArray <ParameterInfo> {
                                    Array = parameters, Length = parameters.Length - 1
                                }.GetArray(parameter => parameter.ParameterType));
                                MethodBuilder setMethodBuilder = typeBuilder.DefineMethod(method.MethodInfo.Name, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Virtual, method.MethodInfo.ReturnType, parameters.getArray(parameter => parameter.ParameterType));
                                ILGenerator   methodGenerator  = setMethodBuilder.GetILGenerator();
                                //XXX
                                propertyBuilder.SetSetMethod(setMethodBuilder);
                                method.PropertyBuilder = null;
                            }
                        }
                        else
                        {
                            Type[]          parameterTypes   = method.MethodInfo.GetParameters().getArray(parameter => parameter.ParameterType);
                            PropertyBuilder propertyBuilder  = typeBuilder.DefineProperty(method.PropertyInfo.Name, PropertyAttributes.HasDefault, method.MethodInfo.ReturnType, parameterTypes);
                            MethodBuilder   getMethodBuilder = typeBuilder.DefineMethod(method.MethodInfo.Name, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Virtual, method.MethodInfo.ReturnType, parameterTypes);
                            ILGenerator     methodGenerator  = getMethodBuilder.GetILGenerator();
                            //XXX
                            propertyBuilder.SetGetMethod(getMethodBuilder);
                            if (method.PropertySetMethod != null)
                            {
                                method = method.PropertySetMethod;
                                method.PropertyBuilder = propertyBuilder;
                                goto METHOD;
                            }
                        }
                    }
                }
                staticConstructorGenerator.Emit(OpCodes.Ret);
                return(typeBuilder.CreateType());
            }
예제 #2
0
            /// <summary>
            /// 创建 TCP 服务端
            /// </summary>
            /// <param name="type"></param>
            /// <param name="attribute"></param>
            /// <param name="serverInterfaceType"></param>
            /// <param name="serverCallType"></param>
            /// <param name="constructorParameterTypes"></param>
            /// <param name="methods"></param>
            /// <returns></returns>
            internal Type Build(Type type, ServerAttribute attribute, Type serverInterfaceType, Type serverCallType, Type[] constructorParameterTypes, Method <attributeType, methodAttributeType, serverSocketType>[] methods)
            {
                string             serverIdentity       = Interlocked.Increment(ref Metadata.Identity).toString();
                TypeBuilder        typeBuilder          = AutoCSer.Emit.Builder.Module.Builder.DefineType(Metadata.ServerTypeName + ".Emit." + type.FullName, TypeAttributes.Class | TypeAttributes.Sealed, Metadata.ServerType);
                FieldBuilder       valueFieldBuilder    = typeBuilder.DefineField("_value_", typeof(object), FieldAttributes.Private | FieldAttributes.InitOnly);
                ConstructorBuilder constructorBuilder   = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, constructorParameterTypes);
                ILGenerator        constructorGenerator = constructorBuilder.GetILGenerator();
                Label serverAttributeNotNull            = constructorGenerator.DefineLabel();
                bool  isCallQueue = false;

                foreach (Method <attributeType, methodAttributeType, serverSocketType> method in methods)
                {
                    if (method != null && (isCallQueue |= method.Attribute.ServerTaskType == TcpServer.ServerTaskType.Queue))
                    {
                        break;
                    }
                }
                #region base(attribute, verify, log, isCallQueue)
                constructorGenerator.Emit(OpCodes.Ldarg_0);
                constructorGenerator.Emit(OpCodes.Ldarg_1);
                constructorGenerator.Emit(OpCodes.Ldarg_2);
                constructorGenerator.Emit(OpCodes.Ldarg_S, 4);
                constructorGenerator.int32(isCallQueue ? 1 : 0);
                constructorGenerator.Emit(OpCodes.Call, Metadata.ServerConstructorInfo);
                #endregion
                #region _value_ = value;
                constructorGenerator.Emit(OpCodes.Ldarg_0);
                constructorGenerator.Emit(OpCodes.Ldarg_3);
                constructorGenerator.Emit(OpCodes.Stfld, valueFieldBuilder);
                #endregion
                constructorGenerator.Emit(OpCodes.Ret);

                ConstructorBuilder staticConstructorBuilder   = typeBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, null);
                ILGenerator        staticConstructorGenerator = staticConstructorBuilder.GetILGenerator();
                #region public override bool DoCommand(int index, AutoCSer.Net.TcpInternalSimpleServer.ServerSocket socket, ref SubArray<byte> data)
                MethodBuilder doCommandMethodBuilder = typeBuilder.DefineMethod("DoCommand", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.ReuseSlot, typeof(bool), Metadata.DoCommandParameterTypes);
                #endregion
                ILGenerator doCommandGenerator = doCommandMethodBuilder.GetILGenerator();
                doCommandGenerator.DeclareLocal(typeof(int));
                Label   doCommandReturnLabel = doCommandGenerator.DefineLabel();
                Label[] doCommandLabels      = new Label[methods.Length];
                int     doCommandLabelIndex  = 0;
                foreach (Method <attributeType, methodAttributeType, serverSocketType> method in methods)
                {
                    doCommandLabels[doCommandLabelIndex++] = method == null ? doCommandReturnLabel : (method.DoCommandLabel = doCommandGenerator.DefineLabel());
                }
                #region switch (index - @CommandStartIndex)
                doCommandGenerator.Emit(OpCodes.Ldarg_1);
                doCommandGenerator.int32(TcpServer.Server.CommandStartIndex);
                doCommandGenerator.Emit(OpCodes.Sub);
                doCommandGenerator.Emit(OpCodes.Stloc_0);
                doCommandGenerator.Emit(OpCodes.Ldloc_0);
                doCommandGenerator.Emit(OpCodes.Switch, doCommandLabels);
                doCommandGenerator.MarkLabel(doCommandReturnLabel);
                doCommandGenerator.int32(0);
                doCommandGenerator.Emit(OpCodes.Ret);
                #endregion
                Outputs = new TcpSimpleServer.OutputInfo[methods.Length];
                FieldInfo outputsField = serverInterfaceType.GetField("Outputs", BindingFlags.Static | BindingFlags.NonPublic);
                foreach (Method <attributeType, methodAttributeType, serverSocketType> method in methods)
                {
                    if (method != null)
                    {
                        FieldBuilder outputInfoFieldBuilder;
                        if (method.OutputParameterType == null && !method.IsAsynchronousCallback)
                        {
                            outputInfoFieldBuilder = null;
                        }
                        else
                        {
                            TcpSimpleServer.OutputInfo outputInfo = new TcpSimpleServer.OutputInfo();
                            Outputs[method.Attribute.CommandIdentity] = outputInfo;
                            if (method.OutputParameterType != null)
                            {
                                outputInfo.OutputParameterIndex = method.OutputParameterType.Index;
                                if (attribute.IsSimpleSerialize)
                                {
                                    outputInfo.IsSimpleSerializeOutputParamter = method.OutputParameterType.IsSimpleSerialize && SimpleSerialize.Serializer.IsType(method.ReturnType);
                                }
                            }
                            #region private static readonly AutoCSer.Net.TcpSimpleServer.OutputInfo @MethodIdentityCommand = AutoCSer.Net.TcpInternalSimpleServer.Emit.Server<interfaceType>.Outputs[@CommandIdentity];
                            staticConstructorGenerator.Emit(OpCodes.Ldsfld, outputsField);
                            staticConstructorGenerator.int32(method.Attribute.CommandIdentity);
                            staticConstructorGenerator.Emit(OpCodes.Ldelem_Ref);
                            staticConstructorGenerator.Emit(OpCodes.Stsfld, outputInfoFieldBuilder = typeBuilder.DefineField("_o" + method.Attribute.CommandIdentity.toString(), typeof(TcpServer.OutputInfo), FieldAttributes.Private | FieldAttributes.InitOnly | FieldAttributes.Static));
                            #endregion
                        }
                        ParameterInfo[] parameters = method.MethodInfo.GetParameters();
                        TypeBuilder     serverCallTypeBuilder;
                        FieldInfo       returnTypeField  = method.ReturnValueType == null ? null : (method.ReturnValueType == typeof(TcpServer.ReturnValue) ? TcpServer.Emit.ServerMetadata.ReturnValueTypeField : method.ReturnValueType.GetField(TcpServer.Emit.ServerMetadata.ReturnValueTypeField.Name, BindingFlags.Instance | BindingFlags.Public));
                        FieldInfo       returnValueField = method.ReturnValueType == null ? null : method.ReturnValueType.GetField("Value", BindingFlags.Instance | BindingFlags.Public);
                        if (method.IsMethodServerCall)
                        {
                            Type      baseType            = method.ParameterType == null ? Metadata.ServerCallType : serverCallType.MakeGenericType(method.ParameterType.Type);
                            FieldInfo inputParameterField = method.ParameterType == null ? null : baseType.GetField("inputParameter", BindingFlags.Instance | BindingFlags.NonPublic);
                            serverCallTypeBuilder = typeBuilder.DefineNestedType(Metadata.ServerCallTypeName + ".Emit." + serverIdentity + "_" + method.Attribute.CommandIdentity.toString(), TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.NestedPublic, baseType);
                            Type      returnOutputType       = method.OutputParameterType == null ? typeof(AutoCSer.Net.TcpServer.ReturnValue) : typeof(AutoCSer.Net.TcpServer.ReturnValue <>).MakeGenericType(method.OutputParameterType.Type);
                            FieldInfo returnOutputValueField = method.OutputParameterType == null ? null : returnOutputType.GetField("Value", BindingFlags.Instance | BindingFlags.Public);
                            Type      returnOutputRefType    = returnOutputType.MakeByRefType();
                            #region private void get(ref AutoCSer.Net.TcpServer.ReturnValue<@OutputParameterTypeName> value)
                            MethodBuilder getMethodBuilder = serverCallTypeBuilder.DefineMethod("get", MethodAttributes.Private, typeof(void), new Type[] { returnOutputRefType });
                            #endregion
                            ILGenerator  getGenerator               = getMethodBuilder.GetILGenerator();
                            Label        getReturnLabel             = getGenerator.DefineLabel();
                            LocalBuilder exceptionErrorLocalBuilder = getGenerator.DeclareLocal(typeof(Exception));
                            #region try
                            getGenerator.BeginExceptionBlock();
                            #endregion
                            #region @MethodReturnType.FullName @ReturnName = serverValue.@MethodName(Socket, inputParameter.@ParameterName);
                            LocalBuilder returnLocalBuilder = method.IsReturnType ? getGenerator.DeclareLocal(method.ReturnValueType ?? method.ReturnType) : null;
                            getGenerator.Emit(OpCodes.Ldarg_0);
                            getGenerator.Emit(OpCodes.Ldfld, Metadata.ServerCallServerValueField);
                            foreach (ParameterInfo parameter in parameters)
                            {
                                if (SimpleParameterType.IsInputParameter(parameter))
                                {
                                    getGenerator.Emit(OpCodes.Ldarg_0);
                                    getGenerator.Emit(OpCodes.Ldflda, inputParameterField);
                                    getGenerator.Emit(parameter.ParameterType.IsByRef ? OpCodes.Ldflda : OpCodes.Ldfld, method.ParameterType.GetField(parameter.Name));
                                }
                                else if (parameter.IsOut)
                                {
                                    getGenerator.Emit(OpCodes.Ldarg_1);
                                    getGenerator.Emit(OpCodes.Ldflda, returnOutputValueField);
                                    getGenerator.Emit(OpCodes.Ldflda, method.OutputParameterType.GetField(parameter.Name));
                                }
                                else if (parameter.ParameterType == Metadata.SocketType)
                                {
                                    getGenerator.Emit(OpCodes.Ldarg_0);
                                    getGenerator.Emit(OpCodes.Ldfld, Metadata.ServerCallSocketField);
                                }
                                else
                                {
                                    getGenerator.Emit(OpCodes.Ldnull);
                                }
                            }
                            getGenerator.call(method.MethodInfo);
                            if (method.IsReturnType)
                            {
                                getGenerator.Emit(OpCodes.Stloc_S, returnLocalBuilder);
                            }
                            #endregion
                            FieldInfo returnValueTypeField = method.OutputParameterType == null ? TcpServer.Emit.ServerMetadata.ReturnValueTypeField : returnOutputType.GetField(TcpServer.Emit.ServerMetadata.ReturnValueTypeField.Name, BindingFlags.Instance | BindingFlags.Public);
                            if (method.OutputParameterType == null)
                            {
                                if (method.ReturnValueType != null)
                                {
                                    Label returnTypeErrorLabel = getGenerator.DefineLabel();
                                    #region if(@ReturnName.Type != AutoCSer.Net.TcpServer.ReturnType.Success)
                                    getGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder);
                                    getGenerator.Emit(OpCodes.Ldfld, returnTypeField);
                                    getGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.Success);
                                    getGenerator.Emit(OpCodes.Beq_S, returnTypeErrorLabel);
                                    #endregion
                                    #region value.Type = @ReturnName.Type;
                                    getGenerator.Emit(OpCodes.Ldarg_1);
                                    getGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder);
                                    getGenerator.Emit(OpCodes.Ldfld, returnTypeField);
                                    getGenerator.Emit(OpCodes.Stfld, returnValueTypeField);
                                    #endregion
                                    getGenerator.Emit(OpCodes.Leave_S, getReturnLabel);
                                    getGenerator.MarkLabel(returnTypeErrorLabel);
                                }
                                #region value.Type = AutoCSer.Net.TcpServer.ReturnType.Success;
                                getGenerator.Emit(OpCodes.Ldarg_1);
                                getGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.Success);
                                getGenerator.Emit(OpCodes.Stfld, returnValueTypeField);
                                #endregion
                                getGenerator.Emit(OpCodes.Leave_S, getReturnLabel);
                            }
                            else
                            {
                                Label returnTypeErrorLabel;
                                if (method.ReturnValueType == null)
                                {
                                    returnTypeErrorLabel = default(Label);
                                }
                                else
                                {
                                    #region if(@ReturnName.Type != AutoCSer.Net.TcpServer.ReturnType.Success)
                                    getGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder);
                                    getGenerator.Emit(OpCodes.Ldfld, returnTypeField);
                                    getGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.Success);
                                    getGenerator.Emit(OpCodes.Bne_Un, returnTypeErrorLabel = getGenerator.DefineLabel());
                                    #endregion
                                }
                                if (method.Attribute.IsVerifyMethod)
                                {
                                    Label verifyEndLabel = getGenerator.DefineLabel();
                                    #region if (@ReturnName / @ReturnName.Value)
                                    if (method.ReturnValueType == null)
                                    {
                                        getGenerator.Emit(OpCodes.Ldloc_S, returnLocalBuilder);
                                    }
                                    else
                                    {
                                        getGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder);
                                        getGenerator.Emit(OpCodes.Ldfld, returnValueField);
                                    }
                                    getGenerator.Emit(OpCodes.Brfalse_S, verifyEndLabel);
                                    #endregion
                                    #region Socket.SetVerifyMethod();
                                    getGenerator.Emit(OpCodes.Ldarg_0);
                                    getGenerator.Emit(OpCodes.Ldfld, Metadata.ServerCallSocketField);
                                    getGenerator.call(ServerMetadata.ServerSocketSetVerifyMethodMethod);
                                    #endregion
                                    getGenerator.MarkLabel(verifyEndLabel);
                                }
                                LocalBuilder valueLocalBuilder = getGenerator.DeclareLocal(method.OutputParameterType.Type);
                                #region value.Value.@ParameterName = inputParameter.@ParameterName;
                                foreach (ParameterInfo parameter in method.OutputParameters)
                                {
                                    if (!parameter.IsOut)
                                    {
                                        getGenerator.Emit(OpCodes.Ldarg_1);
                                        getGenerator.Emit(OpCodes.Ldflda, returnOutputValueField);
                                        getGenerator.Emit(OpCodes.Ldarg_0);
                                        getGenerator.Emit(OpCodes.Ldflda, inputParameterField);
                                        getGenerator.Emit(OpCodes.Ldfld, method.ParameterType.GetField(parameter.Name));
                                        getGenerator.Emit(OpCodes.Stfld, method.OutputParameterType.GetField(parameter.Name));
                                    }
                                }
                                #endregion
                                if (method.ReturnType != typeof(void))
                                {
                                    #region value.Value.@ReturnName = @ReturnName / @ReturnName.Value;
                                    getGenerator.Emit(OpCodes.Ldarg_1);
                                    getGenerator.Emit(OpCodes.Ldflda, returnOutputValueField);
                                    if (method.ReturnValueType == null)
                                    {
                                        getGenerator.Emit(OpCodes.Ldloc_S, returnLocalBuilder);
                                    }
                                    else
                                    {
                                        getGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder);
                                        getGenerator.Emit(OpCodes.Ldfld, returnValueField);
                                    }
                                    getGenerator.Emit(OpCodes.Stfld, method.OutputParameterType.GetField(TcpServer.ReturnValue.RetParameterName));
                                    #endregion
                                }
                                #region value.Type = AutoCSer.Net.TcpServer.ReturnType.Success;
                                getGenerator.Emit(OpCodes.Ldarg_1);
                                getGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.Success);
                                getGenerator.Emit(OpCodes.Stfld, returnValueTypeField);
                                #endregion
                                getGenerator.Emit(OpCodes.Leave_S, getReturnLabel);
                                if (method.ReturnValueType != null)
                                {
                                    getGenerator.MarkLabel(returnTypeErrorLabel);
                                    #region value.Type = @ReturnName.Type;
                                    getGenerator.Emit(OpCodes.Ldarg_1);
                                    getGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder);
                                    getGenerator.Emit(OpCodes.Ldfld, returnTypeField);
                                    getGenerator.Emit(OpCodes.Stfld, returnValueTypeField);
                                    #endregion
                                    getGenerator.Emit(OpCodes.Leave_S, getReturnLabel);
                                }
                            }
                            #region catch (Exception error)
                            getGenerator.BeginCatchBlock(typeof(Exception));
                            getGenerator.Emit(OpCodes.Stloc_S, exceptionErrorLocalBuilder);
                            #endregion
                            #region value.Type = AutoCSer.Net.TcpServer.ReturnType.ServerException;
                            getGenerator.Emit(OpCodes.Ldarg_1);
                            getGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.ServerException);
                            getGenerator.Emit(OpCodes.Stfld, returnValueTypeField);
                            #endregion
                            #region Socket.Log(error);
                            getGenerator.Emit(OpCodes.Ldarg_0);
                            getGenerator.Emit(OpCodes.Ldfld, Metadata.ServerCallSocketField);
                            getGenerator.Emit(OpCodes.Ldloc_S, exceptionErrorLocalBuilder);
                            getGenerator.call(Metadata.ServerSocketLogMethod);
                            #endregion
                            getGenerator.Emit(OpCodes.Leave_S, getReturnLabel);
                            #region try end
                            getGenerator.EndExceptionBlock();
                            #endregion
                            getGenerator.MarkLabel(getReturnLabel);
                            getGenerator.Emit(OpCodes.Ret);

                            #region public override void Call()
                            MethodBuilder callMethodBuilder = serverCallTypeBuilder.DefineMethod("Call", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.ReuseSlot, typeof(void), null);
                            #endregion
                            ILGenerator callGenerator = callMethodBuilder.GetILGenerator();
                            #region AutoCSer.Net.TcpInternalSimpleServer.ServerSocket socket = Socket;
                            LocalBuilder socketBuilder = callGenerator.DeclareLocal(typeof(serverSocketType));
                            getGenerator.Emit(OpCodes.Ldarg_0);
                            getGenerator.Emit(OpCodes.Ldfld, Metadata.ServerCallSocketField);
                            callGenerator.Emit(OpCodes.Stloc_S, socketBuilder);
                            #endregion
                            #region AutoCSer.Net.TcpServer.ReturnValue<@OutputParameterTypeName> value = new AutoCSer.Net.TcpServer.ReturnValue<@OutputParameterTypeName>();
                            LocalBuilder valueBuilder = callGenerator.DeclareLocal(returnOutputType);
                            if (method.OutputParameterType == null || method.Attribute.IsInitobj || method.OutputParameterType.IsInitobj)
                            {
                                callGenerator.Emit(OpCodes.Ldloca_S, valueBuilder);
                                callGenerator.Emit(OpCodes.Initobj, returnOutputType);
                            }
                            else
                            {
                                callGenerator.Emit(OpCodes.Ldloca_S, valueBuilder);
                                callGenerator.int32(0);
                                callGenerator.Emit(OpCodes.Stfld, returnValueTypeField);
                            }
                            #endregion
                            #region get(ref value);
                            callGenerator.Emit(OpCodes.Ldarg_0);
                            callGenerator.Emit(OpCodes.Ldloca_S, valueBuilder);
                            callGenerator.call(getMethodBuilder);
                            #endregion
                            #region push(this);
                            callGenerator.Emit(OpCodes.Ldarg_0);
                            callGenerator.Emit(OpCodes.Ldarg_0);
                            callGenerator.call((method.ParameterType == null ? Metadata.ServerCallPushMethod : serverCallType.MakeGenericType(method.ParameterType.Type).GetMethod("push", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)).MakeGenericMethod(serverCallTypeBuilder));
                            #endregion
                            if (method.OutputParameterType == null)
                            {
                                #region socket.SendAsync(value.Type);
                                callGenerator.Emit(OpCodes.Ldloc_S, socketBuilder);
                                callGenerator.Emit(OpCodes.Ldloca_S, valueBuilder);
                                callGenerator.Emit(OpCodes.Ldfld, returnValueTypeField);
                                callGenerator.call(Metadata.ServerSocketSendAsyncMethod);
                                callGenerator.Emit(OpCodes.Pop);
                                #endregion
                            }
                            else
                            {
                                #region socket.SendAsync(@MethodIdentityCommand, ref value);
                                callGenerator.Emit(OpCodes.Ldloc_S, socketBuilder);
                                callGenerator.Emit(OpCodes.Ldsfld, outputInfoFieldBuilder);
                                callGenerator.Emit(OpCodes.Ldloca_S, valueBuilder);
                                callGenerator.call(Metadata.ServerSocketSendAsyncOutputMethod.MakeGenericMethod(method.OutputParameterType.Type));
                                callGenerator.Emit(OpCodes.Pop);
                                #endregion
                            }
                            callGenerator.Emit(OpCodes.Ret);
                            serverCallTypeBuilder.CreateType();
                        }
                        else
                        {
                            serverCallTypeBuilder = null;
                        }

                        #region private bool @MethodIndexName(AutoCSer.Net.TcpInternalSimpleServer.ServerSocket socket, ref SubArray<byte> data)
                        MethodBuilder methodBuilder = typeBuilder.DefineMethod("_m" + method.Attribute.CommandIdentity.toString(), MethodAttributes.Private, typeof(bool), Metadata.MethodParameterTypes);
                        #endregion
                        ILGenerator methodGenerator = methodBuilder.GetILGenerator();
                        if (method.Attribute.IsExpired)
                        {
                            if (method.OutputParameterType == null)
                            {
                                #region return socket.Send(AutoCSer.Net.TcpServer.ReturnType.VersionExpired);
                                methodGenerator.Emit(OpCodes.Ldarg_1);
                                methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.VersionExpired);
                                methodGenerator.call(Metadata.ServerSocketSendReturnTypeMethod);
                                methodGenerator.Emit(OpCodes.Ret);
                                #endregion
                            }
                            else
                            {
                                #region return socket.SendOutput(AutoCSer.Net.TcpServer.ReturnType.VersionExpired);
                                methodGenerator.Emit(OpCodes.Ldarg_1);
                                methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.VersionExpired);
                                methodGenerator.call(Metadata.ServerSocketSendOutputReturnTypeMethod);
                                methodGenerator.Emit(OpCodes.Ret);
                                #endregion
                            }
                        }
                        else
                        {
                            Label pushLabel = methodGenerator.DefineLabel(), returnLable = methodGenerator.DefineLabel();
                            #region bool isReturnLocalBuilder = false;
                            LocalBuilder isReturnLocalBuilder = methodGenerator.DeclareLocal(typeof(bool));
                            methodGenerator.int32(0);
                            methodGenerator.Emit(OpCodes.Stloc_S, isReturnLocalBuilder);
                            #endregion
                            #region AutoCSer.Net.TcpServer.ReturnType returnType = AutoCSer.Net.TcpServer.ReturnType.Unknown;
                            LocalBuilder returnTypeLocalBuilder = methodGenerator.DeclareLocal(typeof(AutoCSer.Net.TcpServer.ReturnType));
                            methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.Unknown);
                            methodGenerator.Emit(OpCodes.Stloc_S, returnTypeLocalBuilder);
                            #endregion
                            #region try
                            methodGenerator.BeginExceptionBlock();
                            #endregion
                            LocalBuilder parameterLocalBuilder, outputParameterLocalBuilder = null;
                            Label        serverDeSerializeErrorLabel;
                            if (method.ParameterType == null)
                            {
                                parameterLocalBuilder       = null;
                                serverDeSerializeErrorLabel = default(Label);
                            }
                            else
                            {
                                #region @InputParameterTypeName inputParameter = new @InputParameterTypeName();
                                parameterLocalBuilder = methodGenerator.DeclareLocal(method.ParameterType.Type);
                                if (method.Attribute.IsInitobj || method.ParameterType.IsInitobj)
                                {
                                    methodGenerator.Emit(OpCodes.Ldloca_S, parameterLocalBuilder);
                                    methodGenerator.Emit(OpCodes.Initobj, method.ParameterType.Type);
                                }
                                #endregion
                                #region if (socket.DeSerialize(ref data, ref inputParameter))
                                methodGenerator.Emit(OpCodes.Ldarg_1);
                                methodGenerator.Emit(OpCodes.Ldarg_2);
                                methodGenerator.Emit(OpCodes.Ldloca_S, parameterLocalBuilder);
                                methodGenerator.int32(method.ParameterType.IsSimpleSerialize ? 1 : 0);
                                methodGenerator.call(ServerMetadata.ServerSocketDeSerializeMethod.MakeGenericMethod(method.ParameterType.Type));
                                methodGenerator.Emit(OpCodes.Brfalse, serverDeSerializeErrorLabel = methodGenerator.DefineLabel());
                                #endregion
                            }
                            if (method.IsMethodServerCall)
                            {
                                #region @MethodStreamName.Call(socket, _value_, @ServerTask, ref inputParameter);
                                methodGenerator.Emit(OpCodes.Ldarg_1);
                                methodGenerator.Emit(OpCodes.Ldarg_0);
                                methodGenerator.Emit(OpCodes.Ldfld, valueFieldBuilder);
                                methodGenerator.int32((byte)method.ServerTask);
                                if (method.ParameterType == null)
                                {
                                    methodGenerator.call(Metadata.ServerCallCallMethod.MakeGenericMethod(serverCallTypeBuilder));
                                }
                                else
                                {
                                    methodGenerator.Emit(OpCodes.Ldloca_S, parameterLocalBuilder);
                                    methodGenerator.call(serverCallType.MakeGenericType(method.ParameterType.Type).GetMethod("Call", BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly).MakeGenericMethod(serverCallTypeBuilder));
                                }
                                #endregion
                                #region isReturnLocalBuilder = true;
                                methodGenerator.int32(1);
                                methodGenerator.Emit(OpCodes.Stloc_S, isReturnLocalBuilder);
                                #endregion
                            }
                            else
                            {
                                if (method.OutputParameterType != null)
                                {
                                    #region @OutputParameterTypeName outputParameter = new @OutputParameterTypeName();
                                    outputParameterLocalBuilder = methodGenerator.DeclareLocal(method.OutputParameterType.Type);
                                    if (method.Attribute.IsInitobj || method.OutputParameterType.IsInitobj)
                                    {
                                        methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Initobj, method.OutputParameterType.Type);
                                    }
                                    #endregion
                                }
                                #region @MethodReturnType.FullName @ReturnName = _value_.@MethodName(socket, inputParameter.@ParameterName);
                                LocalBuilder returnLocalBuilder = method.IsReturnType ? methodGenerator.DeclareLocal(method.ReturnValueType ?? method.ReturnType) : null;
                                methodGenerator.Emit(OpCodes.Ldarg_0);
                                methodGenerator.Emit(OpCodes.Ldfld, valueFieldBuilder);
                                foreach (ParameterInfo parameter in parameters)
                                {
                                    if (SimpleParameterType.IsInputParameter(parameter))
                                    {
                                        methodGenerator.Emit(OpCodes.Ldloca_S, parameterLocalBuilder);
                                        methodGenerator.Emit(parameter.ParameterType.IsByRef ? OpCodes.Ldflda : OpCodes.Ldfld, method.ParameterType.GetField(parameter.Name));
                                    }
                                    else if (parameter.IsOut)
                                    {
                                        methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Ldflda, method.OutputParameterType.GetField(parameter.Name));
                                    }
                                    else if (parameter.ParameterType == Metadata.SocketType)
                                    {
                                        methodGenerator.Emit(OpCodes.Ldarg_1);
                                    }
                                    else
                                    {
                                        methodGenerator.Emit(OpCodes.Ldnull);
                                    }
                                }
                                methodGenerator.call(method.MethodInfo);
                                if (method.IsReturnType)
                                {
                                    methodGenerator.Emit(OpCodes.Stloc_S, returnLocalBuilder);
                                }
                                #endregion
                                if (method.OutputParameterType == null)
                                {
                                    if (method.ReturnValueType == null)
                                    {
                                        #region return socket.Send();
                                        methodGenerator.Emit(OpCodes.Ldarg_1);
                                        methodGenerator.call(Metadata.ServerSocketSendMethod);
                                        methodGenerator.Emit(OpCodes.Stloc_S, isReturnLocalBuilder);
                                        #endregion
                                    }
                                    else
                                    {
                                        #region return socket.Send(@ReturnName.Type);
                                        methodGenerator.Emit(OpCodes.Ldarg_1);
                                        methodGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Ldfld, returnTypeField);
                                        methodGenerator.call(Metadata.ServerSocketSendReturnTypeMethod);
                                        methodGenerator.Emit(OpCodes.Stloc_S, isReturnLocalBuilder);
                                        #endregion
                                    }
                                }
                                else
                                {
                                    Label returnTypeErrorLabel;
                                    if (method.ReturnValueType == null)
                                    {
                                        returnTypeErrorLabel = default(Label);
                                    }
                                    else
                                    {
                                        #region if(@ReturnName.Type == AutoCSer.Net.TcpServer.ReturnType.Success)
                                        methodGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Ldfld, returnTypeField);
                                        methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.Success);
                                        methodGenerator.Emit(OpCodes.Bne_Un, returnTypeErrorLabel = methodGenerator.DefineLabel());
                                        #endregion
                                    }
                                    if (method.Attribute.IsVerifyMethod)
                                    {
                                        Label verifyEndLabel = methodGenerator.DefineLabel();
                                        #region if (@ReturnName / @ReturnName.Value)
                                        if (method.ReturnValueType == null)
                                        {
                                            methodGenerator.Emit(OpCodes.Ldloc_S, returnLocalBuilder);
                                        }
                                        else
                                        {
                                            methodGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder);
                                            methodGenerator.Emit(OpCodes.Ldfld, returnValueField);
                                        }
                                        methodGenerator.Emit(OpCodes.Brfalse_S, verifyEndLabel);
                                        #endregion
                                        #region socket.SetVerifyMethod();
                                        methodGenerator.Emit(OpCodes.Ldarg_1);
                                        methodGenerator.call(ServerMetadata.ServerSocketSetVerifyMethodMethod);
                                        #endregion
                                        methodGenerator.MarkLabel(verifyEndLabel);
                                    }
                                    foreach (ParameterInfo parameter in method.OutputParameters)
                                    {
                                        if (!parameter.IsOut)
                                        {
                                            #region outputParameter.@ParameterName = inputParameter.@ParameterName
                                            methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder);
                                            methodGenerator.Emit(OpCodes.Ldloca_S, parameterLocalBuilder);
                                            methodGenerator.Emit(OpCodes.Ldfld, method.ParameterType.GetField(parameter.Name));
                                            methodGenerator.Emit(OpCodes.Stfld, method.OutputParameterType.GetField(parameter.Name));
                                            #endregion
                                        }
                                    }
                                    if (method.ReturnType != typeof(void))
                                    {
                                        #region _outputParameter_.Ret = @ReturnName / @ReturnName.Value
                                        methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder);
                                        if (method.ReturnValueType == null)
                                        {
                                            methodGenerator.Emit(OpCodes.Ldloc_S, returnLocalBuilder);
                                        }
                                        else
                                        {
                                            methodGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder);
                                            methodGenerator.Emit(OpCodes.Ldfld, returnValueField);
                                        }
                                        methodGenerator.Emit(OpCodes.Stfld, method.OutputParameterType.GetField(TcpServer.ReturnValue.RetParameterName));
                                        #endregion
                                    }

                                    #region return socket.Send(@MethodIdentityCommand, ref outputParameter)
                                    methodGenerator.Emit(OpCodes.Ldarg_1);
                                    methodGenerator.Emit(OpCodes.Ldsfld, outputInfoFieldBuilder);
                                    methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder);
                                    methodGenerator.call(Metadata.ServerSocketSendOutputMethod.MakeGenericMethod(method.OutputParameterType.Type));
                                    methodGenerator.Emit(OpCodes.Stloc_S, isReturnLocalBuilder);
                                    #endregion
                                    methodGenerator.Emit(OpCodes.Leave_S, returnLable);
                                    if (method.ReturnValueType != null)
                                    {
                                        methodGenerator.MarkLabel(returnTypeErrorLabel);
                                        #region return socket.SendOutput(@ReturnValue.Type);
                                        methodGenerator.Emit(OpCodes.Ldarg_1);
                                        methodGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Ldfld, returnTypeField);
                                        methodGenerator.call(Metadata.ServerSocketSendOutputReturnTypeMethod);
                                        methodGenerator.Emit(OpCodes.Stloc_S, isReturnLocalBuilder);
                                        #endregion
                                    }
                                }
                            }
                            methodGenerator.Emit(OpCodes.Leave_S, returnLable);
                            if (method.ParameterType != null)
                            {
                                methodGenerator.MarkLabel(serverDeSerializeErrorLabel);
                                #region returnType = AutoCSer.Net.TcpServer.ReturnType.ServerDeSerializeError;
                                methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.ServerDeSerializeError);
                                methodGenerator.Emit(OpCodes.Stloc_S, returnTypeLocalBuilder);
                                #endregion
                                methodGenerator.Emit(OpCodes.Leave_S, pushLabel);
                            }
                            #region catch (Exception error)
                            methodGenerator.BeginCatchBlock(typeof(Exception));
                            LocalBuilder errorLocalBuilder = methodGenerator.DeclareLocal(typeof(Exception));
                            methodGenerator.Emit(OpCodes.Stloc_S, errorLocalBuilder);
                            #endregion
                            #region returnType = AutoCSer.Net.TcpServer.ReturnType.ServerException;
                            methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.ServerException);
                            methodGenerator.Emit(OpCodes.Stloc_S, returnTypeLocalBuilder);
                            #endregion
                            #region socket.Log(error);
                            methodGenerator.Emit(OpCodes.Ldarg_1);
                            methodGenerator.Emit(OpCodes.Ldloc_S, errorLocalBuilder);
                            methodGenerator.call(Metadata.ServerSocketLogMethod);
                            #endregion
                            methodGenerator.Emit(OpCodes.Leave_S, pushLabel);
                            #region try end
                            methodGenerator.EndExceptionBlock();
                            #endregion
                            methodGenerator.MarkLabel(pushLabel);
                            if (method.OutputParameterType == null)
                            {
                                #region return socket.Send(returnType);
                                methodGenerator.Emit(OpCodes.Ldarg_1);
                                methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder);
                                methodGenerator.call(Metadata.ServerSocketSendReturnTypeMethod);
                                methodGenerator.Emit(OpCodes.Ret);
                                #endregion
                            }
                            else
                            {
                                #region return socket.SendOutput(returnType);
                                methodGenerator.Emit(OpCodes.Ldarg_1);
                                methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder);
                                methodGenerator.call(Metadata.ServerSocketSendOutputReturnTypeMethod);
                                methodGenerator.Emit(OpCodes.Ret);
                                #endregion
                            }
                            methodGenerator.MarkLabel(returnLable);
                            methodGenerator.Emit(OpCodes.Ldloc_S, isReturnLocalBuilder);
                            methodGenerator.Emit(OpCodes.Ret);
                        }

                        #region case @MethodIndex: return @MethodIndexName(socket, ref data);
                        doCommandGenerator.MarkLabel(method.DoCommandLabel);
                        doCommandGenerator.Emit(OpCodes.Ldarg_0);
                        doCommandGenerator.Emit(OpCodes.Ldarg_2);
                        doCommandGenerator.Emit(OpCodes.Ldarg_3);
                        doCommandGenerator.call(methodBuilder);
                        doCommandGenerator.Emit(OpCodes.Ret);
                        #endregion
                        method.DoCommandLabel = default(Label);
                    }
                }
                doCommandGenerator.Emit(OpCodes.Ret);
                staticConstructorGenerator.Emit(OpCodes.Ret);

                return(typeBuilder.CreateType());
            }