private void BuildMethodBlock( TypeBuilder typeBuilder, RenderMethodBuilder renderMethodBuilder, PropertyBuilder grpcClientProperty, PropertyBuilder jsonOptionsProperty, int implementedMethods, MethodInfo method, ConstructorBuilder constructorBuilder, PropertyBuilder metadataProviderProperty) { var clientMethodType = method.GetClientMethodType(); var methodTypeName = clientMethodType.ToString(); var requestType = method.GetRequestTypeFromMethod(clientMethodType); var responseType = method.GetResponseTypeFromMethod(clientMethodType); var requestProperty = CreateRequestProperty(typeBuilder, methodTypeName, implementedMethods); var responseProperty = CreateResponseProperty(typeBuilder, methodTypeName, implementedMethods); var blockVisibleProperty = CreateBlockVisiblePropertyProperty(typeBuilder, methodTypeName, implementedMethods); var cancellationTokenSourceField = CreateСancellationTokenSourceField(typeBuilder, methodTypeName, implementedMethods); constructorBuilder.InitializeBoolValue(blockVisibleProperty); constructorBuilder.InitializeStringValue( requestType, jsonOptionsProperty, requestProperty, clientMethodType == ClientMethodType.ClientStreaming || clientMethodType == ClientMethodType.DuplexStreaming); var cancelProcessingMethod = typeBuilder .DefineMethod($"Cancel{methodTypeName}Processing_{implementedMethods}", MethodAttributes.Public | MethodAttributes.Virtual, typeof(void), Type.EmptyTypes) .ImplementCancelProcessing(cancellationTokenSourceField); var clearResponseMethod = typeBuilder .DefineMethod($"Clear{methodTypeName}Response_{implementedMethods}", MethodAttributes.Public | MethodAttributes.Virtual, typeof(void), Type.EmptyTypes) .ImplementClearResponse(cancelProcessingMethod, responseProperty); var invertBlockVisibilityMethod = typeBuilder .DefineMethod($"Invert{methodTypeName}BlockVisibility_{implementedMethods}", MethodAttributes.Public | MethodAttributes.Virtual, typeof(void), Type.EmptyTypes) .ImplementInvertBlockVisibility(blockVisibleProperty); var setResponseWithNotifyMethod = typeBuilder .DefineMethod($"SetResponseFor{methodTypeName}_{implementedMethods}", MethodAttributes.Public | MethodAttributes.Virtual, typeof(Task), new[] { typeof(string) }) .ImplementSetWithNotify(responseProperty); var processingMethod = typeBuilder .DefineMethod($"Process{methodTypeName}Request_{implementedMethods}", MethodAttributes.Public | MethodAttributes.Virtual, typeof(void), Type.EmptyTypes) .ImplementProcessingMethod( grpcClientProperty, requestProperty, cancellationTokenSourceField, jsonOptionsProperty, responseProperty, clientMethodType, method, setResponseWithNotifyMethod, requestType, responseType, metadataProviderProperty, clearResponseMethod); var methodType = methodTypeName.Substring(0, 1).ToLowerInvariant() + methodTypeName.Substring(1, methodTypeName.Length - 1); renderMethodBuilder.OpenRegion(implementedMethods) .OpenElement(0, "div") .AddAttribute(1, "class", $"methodData {methodType}") .AddMarkupContent(2, "\r\n") .OpenElement(3, "div") .AddAttribute(4, "class", "methodHeader") .AddAttribute(5, "onclick", invertBlockVisibilityMethod) .AddMarkupContent(6, "\r\n") .AddMarkupContent(7, $"<div class=\"methodType {methodType}\">{clientMethodType.GetNormalizedName()}</div>\r\n") .AddMarkupContent(8, $"<div class=\"methodDescription\">{method.Name} method</div>\r\n") .CloseElement() .AddMarkupContent(9, "\r\n") .OpenElement(10, "div") .AddAttribute(11, "class", $"methodBody {methodType} ", blockVisibleProperty.GetGetMethod(), "hidden") .AddMarkupContent(12, "\r\n") .AddMarkupContent(13, "<p class=\"requestLabel\">Request values: </p>\r\n") .OpenElement(14, "textarea") .AddAttribute(15, "class", $"requestValue {methodType}") .AddAttribute(16, "value", requestProperty) .AddAttribute(17, "oninput", requestProperty.GetSetMethod(), requestProperty.GetGetMethod()) .SetUpdatesAttributeName("value") .CloseElement() .AddMarkupContent(18, "\r\n\r\n") .OpenElement(19, "button") .AddAttribute(20, "class", $"requestButton execute {methodType}") .AddAttribute(21, "onclick", processingMethod) .AddMarkupContent(22, "\r\nExecute\r\n") .CloseElement() .AddMarkupContent(23, "\r\n") .OpenElement(24, "button") .AddAttribute(25, "class", $"requestButton clear {methodType}") .AddAttribute(26, "onclick", clearResponseMethod) .AddMarkupContent(27, "\r\nClear\r\n") .CloseElement() .AddMarkupContent(28, "\r\n") .OpenElement(29, "button") .AddAttribute(30, "class", $"requestButton cancel {methodType}") .AddAttribute(31, "onclick", cancelProcessingMethod) .AddMarkupContent(32, "\r\nCancel\r\n") .CloseElement() .AddMarkupContent(33, "\r\n\r\n\r\n") .AddMarkupContent(34, "<p class=\"responseLabel\">Response value: </p>\r\n") .OpenElement(35, "pre") .AddAttribute(36, "class", $"responseValue {methodType}") .AddContent(37, responseProperty) .CloseElement() .AddMarkupContent(38, "\r\n") .CloseElement() .AddMarkupContent(39, "\r\n") .CloseElement() .AddMarkupContent(40, "\r\n") .CloseRegion(); }