internal static Assembly GenerateRefEmitAssembly(XmlMapping[] xmlMappings, Type[] types, string defaultNamespace) { var scopeTable = new Dictionary <TypeScope, XmlMapping>(); foreach (XmlMapping mapping in xmlMappings) { scopeTable[mapping.Scope] = mapping; } TypeScope[] scopes = new TypeScope[scopeTable.Keys.Count]; scopeTable.Keys.CopyTo(scopes, 0); string assemblyName = "Microsoft.GeneratedCode"; AssemblyBuilder assemblyBuilder = CodeGenerator.CreateAssemblyBuilder(assemblyName); // Add AssemblyVersion attribute to match parent assembly version if (types != null && types.Length > 0 && types[0] != null) { ConstructorInfo AssemblyVersionAttribute_ctor = typeof(AssemblyVersionAttribute).GetConstructor( new Type[] { typeof(String) } ); string assemblyVersion = types[0].Assembly.GetName().Version.ToString(); assemblyBuilder.SetCustomAttribute(new CustomAttributeBuilder(AssemblyVersionAttribute_ctor, new Object[] { assemblyVersion })); } CodeIdentifiers classes = new CodeIdentifiers(); classes.AddUnique("XmlSerializationWriter", "XmlSerializationWriter"); classes.AddUnique("XmlSerializationReader", "XmlSerializationReader"); string suffix = null; if (types != null && types.Length == 1 && types[0] != null) { suffix = CodeIdentifier.MakeValid(types[0].Name); if (types[0].IsArray) { suffix += "Array"; } } ModuleBuilder moduleBuilder = CodeGenerator.CreateModuleBuilder(assemblyBuilder, assemblyName); string writerClass = "XmlSerializationWriter" + suffix; writerClass = classes.AddUnique(writerClass, writerClass); XmlSerializationWriterILGen writerCodeGen = new XmlSerializationWriterILGen(scopes, "public", writerClass); writerCodeGen.ModuleBuilder = moduleBuilder; writerCodeGen.GenerateBegin(); string[] writeMethodNames = new string[xmlMappings.Length]; for (int i = 0; i < xmlMappings.Length; i++) { writeMethodNames[i] = writerCodeGen.GenerateElement(xmlMappings[i]); } Type writerType = writerCodeGen.GenerateEnd(); string readerClass = "XmlSerializationReader" + suffix; readerClass = classes.AddUnique(readerClass, readerClass); XmlSerializationReaderILGen readerCodeGen = new XmlSerializationReaderILGen(scopes, "public", readerClass); readerCodeGen.ModuleBuilder = moduleBuilder; readerCodeGen.CreatedTypes.Add(writerType.Name, writerType); readerCodeGen.GenerateBegin(); string[] readMethodNames = new string[xmlMappings.Length]; for (int i = 0; i < xmlMappings.Length; i++) { readMethodNames[i] = readerCodeGen.GenerateElement(xmlMappings[i]); } readerCodeGen.GenerateEnd(readMethodNames, xmlMappings, types); string baseSerializer = readerCodeGen.GenerateBaseSerializer("XmlSerializer1", readerClass, writerClass, classes); var serializers = new Dictionary <string, string>(); for (int i = 0; i < xmlMappings.Length; i++) { if (!serializers.ContainsKey(xmlMappings[i].Key)) { serializers[xmlMappings[i].Key] = readerCodeGen.GenerateTypedSerializer(readMethodNames[i], writeMethodNames[i], xmlMappings[i], classes, baseSerializer, readerClass, writerClass); } } readerCodeGen.GenerateSerializerContract("XmlSerializerContract", xmlMappings, types, readerClass, readMethodNames, writerClass, writeMethodNames, serializers); return(writerType.Assembly); }
CodeMemberMethod GenerateMethod(CodeIdentifiers memberIds, HttpOperationBinding httpOper, XmlMembersMapping inputMembers, XmlTypeMapping outputMember) { CodeIdentifiers pids = new CodeIdentifiers(); CodeMemberMethod method = new CodeMemberMethod(); CodeMemberMethod methodBegin = new CodeMemberMethod(); CodeMemberMethod methodEnd = new CodeMemberMethod(); method.Attributes = MemberAttributes.Public; methodBegin.Attributes = MemberAttributes.Public; methodEnd.Attributes = MemberAttributes.Public; // Find unique names for temporary variables for (int n = 0; n < inputMembers.Count; n++) { pids.AddUnique(inputMembers[n].MemberName, inputMembers[n]); } string varAsyncResult = pids.AddUnique("asyncResult", "asyncResult"); string varCallback = pids.AddUnique("callback", "callback"); string varAsyncState = pids.AddUnique("asyncState", "asyncState"); string messageName = memberIds.AddUnique(CodeIdentifier.MakeValid(Operation.Name), method); method.Name = Operation.Name; methodBegin.Name = memberIds.AddUnique(CodeIdentifier.MakeValid("Begin" + Operation.Name), method); methodEnd.Name = memberIds.AddUnique(CodeIdentifier.MakeValid("End" + Operation.Name), method); method.ReturnType = new CodeTypeReference(typeof(void)); methodEnd.ReturnType = new CodeTypeReference(typeof(void)); methodEnd.Parameters.Add(new CodeParameterDeclarationExpression(typeof(IAsyncResult), varAsyncResult)); CodeExpression[] paramArray = new CodeExpression [inputMembers.Count]; for (int n = 0; n < inputMembers.Count; n++) { string ptype = GetSimpleType(inputMembers[n]); CodeParameterDeclarationExpression param = new CodeParameterDeclarationExpression(ptype, inputMembers[n].MemberName); param.Direction = FieldDirection.In; method.Parameters.Add(param); methodBegin.Parameters.Add(param); paramArray [n] = new CodeVariableReferenceExpression(param.Name); } bool isVoid = true; if (outputMember != null) { method.ReturnType = new CodeTypeReference(outputMember.TypeFullName); methodEnd.ReturnType = new CodeTypeReference(outputMember.TypeFullName); xmlExporter.AddMappingMetadata(method.ReturnTypeCustomAttributes, outputMember, ""); isVoid = false; } methodBegin.Parameters.Add(new CodeParameterDeclarationExpression(typeof(AsyncCallback), varCallback)); methodBegin.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), varAsyncState)); methodBegin.ReturnType = new CodeTypeReference(typeof(IAsyncResult)); // Array of input parameters CodeArrayCreateExpression methodParams; if (paramArray.Length > 0) { methodParams = new CodeArrayCreateExpression(typeof(object), paramArray); } else { methodParams = new CodeArrayCreateExpression(typeof(object), 0); } // Generate method url CodeThisReferenceExpression ethis = new CodeThisReferenceExpression(); CodeExpression thisURlExp = new CodeFieldReferenceExpression(ethis, "Url"); CodePrimitiveExpression metUrl = new CodePrimitiveExpression(httpOper.Location); CodeBinaryOperatorExpression expMethodLocation = new CodeBinaryOperatorExpression(thisURlExp, CodeBinaryOperatorType.Add, metUrl); // Invoke call CodePrimitiveExpression varMsgName = new CodePrimitiveExpression(messageName); CodeMethodInvokeExpression inv; inv = new CodeMethodInvokeExpression(ethis, "Invoke", varMsgName, expMethodLocation, methodParams); if (!isVoid) { method.Statements.Add(new CodeMethodReturnStatement(new CodeCastExpression(method.ReturnType, inv))); } else { method.Statements.Add(inv); } // Begin Invoke Call CodeExpression expCallb = new CodeVariableReferenceExpression(varCallback); CodeExpression expAsyncs = new CodeVariableReferenceExpression(varAsyncState); inv = new CodeMethodInvokeExpression(ethis, "BeginInvoke", varMsgName, expMethodLocation, methodParams, expCallb, expAsyncs); methodBegin.Statements.Add(new CodeMethodReturnStatement(inv)); // End Invoke call CodeExpression varAsyncr = new CodeVariableReferenceExpression(varAsyncResult); inv = new CodeMethodInvokeExpression(ethis, "EndInvoke", varAsyncr); if (!isVoid) { methodEnd.Statements.Add(new CodeMethodReturnStatement(new CodeCastExpression(methodEnd.ReturnType, inv))); } else { methodEnd.Statements.Add(inv); } // Attributes CodeAttributeDeclaration att = new CodeAttributeDeclaration("System.Web.Services.Protocols.HttpMethodAttribute"); att.Arguments.Add(new CodeAttributeArgument(new CodeTypeOfExpression(GetOutMimeFormatter()))); att.Arguments.Add(new CodeAttributeArgument(new CodeTypeOfExpression(GetInMimeFormatter()))); AddCustomAttribute(method, att, true); CodeTypeDeclaration.Members.Add(method); CodeTypeDeclaration.Members.Add(methodBegin); CodeTypeDeclaration.Members.Add(methodEnd); return(method); }
internal static bool GenerateSerializerToStream(XmlMapping[] xmlMappings, Type[] types, string defaultNamespace, Assembly assembly, Hashtable assemblies, Stream stream) { var compiler = new Compiler(); try { var scopeTable = new Hashtable(); foreach (XmlMapping mapping in xmlMappings) { scopeTable[mapping.Scope] = mapping; } var scopes = new TypeScope[scopeTable.Keys.Count]; scopeTable.Keys.CopyTo(scopes, 0); assemblies.Clear(); var importedTypes = new Hashtable(); foreach (TypeScope scope in scopes) { foreach (Type t in scope.Types) { compiler.AddImport(t, importedTypes); Assembly a = t.Assembly; string name = a.FullName; if (assemblies[name] != null) { continue; } if (!a.GlobalAssemblyCache) { assemblies[name] = a; } } } for (int i = 0; i < types.Length; i++) { compiler.AddImport(types[i], importedTypes); } compiler.AddImport(typeof(object).Assembly); compiler.AddImport(typeof(System.Xml.Serialization.XmlSerializer).Assembly); var writer = new IndentedWriter(compiler.Source, false); writer.WriteLine("[assembly:System.Security.AllowPartiallyTrustedCallers()]"); writer.WriteLine("[assembly:System.Security.SecurityTransparent()]"); writer.WriteLine("[assembly:System.Security.SecurityRules(System.Security.SecurityRuleSet.Level1)]"); if (assembly != null && types.Length > 0) { for (int i = 0; i < types.Length; i++) { Type type = types[i]; if (type == null) { continue; } if (DynamicAssemblies.IsTypeDynamic(type)) { throw new InvalidOperationException(SR.Format(SR.XmlPregenTypeDynamic, types[i].FullName)); } } writer.Write("[assembly:"); writer.Write(typeof(XmlSerializerVersionAttribute).FullName); writer.Write("("); writer.Write("ParentAssemblyId="); ReflectionAwareCodeGen.WriteQuotedCSharpString(writer, GenerateAssemblyId(types[0])); writer.Write(", Version="); ReflectionAwareCodeGen.WriteQuotedCSharpString(writer, ThisAssembly.Version); if (defaultNamespace != null) { writer.Write(", Namespace="); ReflectionAwareCodeGen.WriteQuotedCSharpString(writer, defaultNamespace); } writer.WriteLine(")]"); } var classes = new CodeIdentifiers(); classes.AddUnique("XmlSerializationWriter", "XmlSerializationWriter"); classes.AddUnique("XmlSerializationReader", "XmlSerializationReader"); string suffix = null; if (types != null && types.Length == 1 && types[0] != null) { suffix = CodeIdentifier.MakeValid(types[0].Name); if (types[0].IsArray) { suffix += "Array"; } } writer.WriteLine("namespace " + GeneratedAssemblyNamespace + " {"); writer.Indent++; writer.WriteLine(); string writerClass = "XmlSerializationWriter" + suffix; writerClass = classes.AddUnique(writerClass, writerClass); var writerCodeGen = new XmlSerializationWriterCodeGen(writer, scopes, "public", writerClass); writerCodeGen.GenerateBegin(); string[] writeMethodNames = new string[xmlMappings.Length]; for (int i = 0; i < xmlMappings.Length; i++) { writeMethodNames[i] = writerCodeGen.GenerateElement(xmlMappings[i]); } writerCodeGen.GenerateEnd(); writer.WriteLine(); string readerClass = "XmlSerializationReader" + suffix; readerClass = classes.AddUnique(readerClass, readerClass); var readerCodeGen = new XmlSerializationReaderCodeGen(writer, scopes, "public", readerClass); readerCodeGen.GenerateBegin(); string[] readMethodNames = new string[xmlMappings.Length]; for (int i = 0; i < xmlMappings.Length; i++) { readMethodNames[i] = readerCodeGen.GenerateElement(xmlMappings[i]); } readerCodeGen.GenerateEnd(readMethodNames, xmlMappings, types); string baseSerializer = readerCodeGen.GenerateBaseSerializer("XmlSerializer1", readerClass, writerClass, classes); var serializers = new Hashtable(); for (int i = 0; i < xmlMappings.Length; i++) { if (serializers[xmlMappings[i].Key] == null) { serializers[xmlMappings[i].Key] = readerCodeGen.GenerateTypedSerializer(readMethodNames[i], writeMethodNames[i], xmlMappings[i], classes, baseSerializer, readerClass, writerClass); } } readerCodeGen.GenerateSerializerContract("XmlSerializerContract", xmlMappings, types, readerClass, readMethodNames, writerClass, writeMethodNames, serializers); writer.Indent--; writer.WriteLine("}"); string codecontent = compiler.Source.ToString(); Byte[] info = new UTF8Encoding(true).GetBytes(codecontent); stream.Write(info, 0, info.Length); stream.Flush(); return(true); } finally { compiler.Close(); } }
void CreateHeaderMessages(string methodName, SoapBindingUse use, XmlMembersMapping inHeaderMappings, XmlMembersMapping outHeaderMappings, SoapReflectedHeader[] headers, bool rpc) { // if (use == SoapBindingUse.Encoded) { SoapExporter.ExportMembersMapping(inHeaderMappings, false); if (outHeaderMappings != null) { SoapExporter.ExportMembersMapping(outHeaderMappings, false); } } else { SchemaExporter.ExportMembersMapping(inHeaderMappings); if (outHeaderMappings != null) { SchemaExporter.ExportMembersMapping(outHeaderMappings); } } CodeIdentifiers identifiers = new CodeIdentifiers(); int inCount = 0, outCount = 0; for (int i = 0; i < headers.Length; i++) { SoapReflectedHeader soapHeader = headers[i]; if (!soapHeader.custom) { continue; } XmlMemberMapping member; if ((soapHeader.direction & SoapHeaderDirection.In) != 0) { member = inHeaderMappings[inCount++]; if (soapHeader.direction != SoapHeaderDirection.In) { outCount++; } } else { member = outHeaderMappings[outCount++]; } MessagePart part = new MessagePart(); part.Name = member.XsdElementName; if (use == SoapBindingUse.Encoded) { part.Type = new XmlQualifiedName(member.TypeName, member.TypeNamespace); } else { part.Element = new XmlQualifiedName(member.XsdElementName, member.Namespace); } Message message = new Message(); message.Name = identifiers.AddUnique(methodName + part.Name, message); message.Parts.Add(part); HeaderMessages.Add(message); ServiceDescriptionFormatExtension soapHeaderBinding = CreateSoapHeaderBinding(new XmlQualifiedName(message.Name, Binding.ServiceDescription.TargetNamespace), part.Name, rpc ? member.Namespace : null, use); if ((soapHeader.direction & SoapHeaderDirection.In) != 0) { OperationBinding.Input.Extensions.Add(soapHeaderBinding); } if ((soapHeader.direction & SoapHeaderDirection.Out) != 0) { OperationBinding.Output.Extensions.Add(soapHeaderBinding); } if ((soapHeader.direction & SoapHeaderDirection.Fault) != 0) { if (soapMethod.IsClaimsConformance) { throw new InvalidOperationException(Res.GetString(Res.BPConformanceHeaderFault, soapMethod.methodInfo.ToString(), soapMethod.methodInfo.DeclaringType.FullName, "Direction", typeof(SoapHeaderDirection).Name, SoapHeaderDirection.Fault.ToString())); } OperationBinding.Output.Extensions.Add(soapHeaderBinding); } } }
void GenerateProxyClass(ContractDescription cd, CodeNamespace cns) { string name = cd.Name + "Client"; if (name [0] == 'I') { name = name.Substring(1); } name = identifiers.AddUnique(name, null); CodeTypeDeclaration type = GetTypeDeclaration(cns, name); if (type != null) { return; // already imported } CodeTypeReference clientBase = new CodeTypeReference(typeof(ClientBase <>)); clientBase.TypeArguments.Add(new CodeTypeReference(cd.Name)); type = new CodeTypeDeclaration(name); cns.Types.Add(type); type.TypeAttributes = TypeAttributes.Public; type.BaseTypes.Add(clientBase); type.BaseTypes.Add(new CodeTypeReference(cd.Name)); // .ctor() CodeConstructor ctor = new CodeConstructor(); ctor.Attributes = MemberAttributes.Public; type.Members.Add(ctor); // .ctor(string endpointConfigurationName) ctor = new CodeConstructor(); ctor.Attributes = MemberAttributes.Public; ctor.Parameters.Add( new CodeParameterDeclarationExpression( new CodeTypeReference(typeof(string)), "endpointConfigurationName")); ctor.BaseConstructorArgs.Add( new CodeArgumentReferenceExpression("endpointConfigurationName")); type.Members.Add(ctor); // .ctor(string endpointConfigurationName, string remoteAddress) ctor = new CodeConstructor(); ctor.Attributes = MemberAttributes.Public; ctor.Parameters.Add( new CodeParameterDeclarationExpression( new CodeTypeReference(typeof(string)), "endpointConfigurationName")); ctor.Parameters.Add( new CodeParameterDeclarationExpression( new CodeTypeReference(typeof(string)), "remoteAddress")); ctor.BaseConstructorArgs.Add( new CodeArgumentReferenceExpression("endpointConfigurationName")); ctor.BaseConstructorArgs.Add( new CodeArgumentReferenceExpression("remoteAddress")); type.Members.Add(ctor); // .ctor(string endpointConfigurationName, EndpointAddress remoteAddress) ctor = new CodeConstructor(); ctor.Attributes = MemberAttributes.Public; ctor.Parameters.Add( new CodeParameterDeclarationExpression( new CodeTypeReference(typeof(string)), "endpointConfigurationName")); ctor.Parameters.Add( new CodeParameterDeclarationExpression( new CodeTypeReference(typeof(EndpointAddress)), "remoteAddress")); ctor.BaseConstructorArgs.Add( new CodeArgumentReferenceExpression("endpointConfigurationName")); ctor.BaseConstructorArgs.Add( new CodeArgumentReferenceExpression("remoteAddress")); type.Members.Add(ctor); // .ctor(Binding,EndpointAddress) ctor = new CodeConstructor(); ctor.Attributes = MemberAttributes.Public; ctor.Parameters.Add( new CodeParameterDeclarationExpression( new CodeTypeReference(typeof(Binding)), "binding")); ctor.Parameters.Add( new CodeParameterDeclarationExpression( new CodeTypeReference(typeof(EndpointAddress)), "endpoint")); ctor.BaseConstructorArgs.Add( new CodeArgumentReferenceExpression("binding")); ctor.BaseConstructorArgs.Add( new CodeArgumentReferenceExpression("endpoint")); type.Members.Add(ctor); // service contract methods AddImplementationClientMethods(type, cd); if (GenerateEventBasedAsync) { foreach (var od in cd.Operations) { GenerateEventBasedAsyncSupport(type, od, cns); } } }
void ImportPortBinding(bool multipleBindings) { if (port != null) { if (multipleBindings) { className = binding.Name; } else { className = service.Name; } } else { className = binding.Name; } className = classNames.AddUnique(CodeIdentifier.MakeValid(className), port); className = className.Replace("_x0020_", ""); // MS.NET seems to do this try { portType = ServiceDescriptions.GetPortType(binding.Type); if (portType == null) { throw new Exception("Port type not found: " + binding.Type); } CodeTypeDeclaration codeClass = BeginClass(); codeTypeDeclaration = codeClass; AddCodeType(codeClass, port != null ? port.Documentation : null); codeClass.Attributes = MemberAttributes.Public; if (service != null && service.Documentation != null && service.Documentation != "") { AddComments(codeClass, service.Documentation); } if (Style == ServiceDescriptionImportStyle.Client) { CodeAttributeDeclaration att = new CodeAttributeDeclaration("System.Diagnostics.DebuggerStepThroughAttribute"); AddCustomAttribute(codeClass, att, true); att = new CodeAttributeDeclaration("System.ComponentModel.DesignerCategoryAttribute"); att.Arguments.Add(GetArg("code")); AddCustomAttribute(codeClass, att, true); } else { codeClass.TypeAttributes = System.Reflection.TypeAttributes.Abstract | System.Reflection.TypeAttributes.Public; } if (binding.Operations.Count == 0) { warnings |= ServiceDescriptionImportWarnings.NoMethodsGenerated; return; } foreach (OperationBinding oper in binding.Operations) { operationBinding = oper; operation = FindPortOperation(); if (operation == null) { throw new Exception("Operation " + operationBinding.Name + " not found in portType " + PortType.Name); } inputMessage = null; outputMessage = null; foreach (OperationMessage omsg in operation.Messages) { Message msg = ServiceDescriptions.GetMessage(omsg.Message); if (msg == null) { throw new Exception("Message not found: " + omsg.Message); } if (omsg is OperationInput) { inputMessage = msg; } else { outputMessage = msg; } } CodeMemberMethod method = GenerateMethod(); if (method != null) { methodName = method.Name; if (operation.Documentation != null && operation.Documentation != "") { AddComments(method, operation.Documentation); } #if NET_2_0 if (Style == ServiceDescriptionImportStyle.Client) { AddAsyncMembers(method.Name, method); } #endif } } #if NET_2_0 if (Style == ServiceDescriptionImportStyle.Client) { AddAsyncTypes(); } #endif EndClass(); } catch (InvalidOperationException ex) { warnings |= ServiceDescriptionImportWarnings.NoCodeGenerated; UnsupportedBindingWarning(ex.Message); } }
void AddAsyncMembers(string messageName, CodeMemberMethod method) { CodeThisReferenceExpression ethis = new CodeThisReferenceExpression(); CodePrimitiveExpression enull = new CodePrimitiveExpression(null); CodeMemberField codeField = new CodeMemberField(typeof(System.Threading.SendOrPostCallback), messageName + "OperationCompleted"); codeField.Attributes = MemberAttributes.Private; CodeTypeDeclaration.Members.Add(codeField); // Event arguments class string argsClassName = classNames.AddUnique(messageName + "CompletedEventArgs", null); CodeTypeDeclaration argsClass = new CodeTypeDeclaration(argsClassName); argsClass.Attributes |= MemberAttributes.Public; #if NET_2_0 argsClass.IsPartial = true; #endif argsClass.BaseTypes.Add(new CodeTypeReference("System.ComponentModel.AsyncCompletedEventArgs")); CodeMemberField resultsField = new CodeMemberField(typeof(object[]), "results"); resultsField.Attributes = MemberAttributes.Private; argsClass.Members.Add(resultsField); CodeConstructor cc = new CodeConstructor(); cc.Attributes = MemberAttributes.Assembly; cc.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object[]), "results")); cc.Parameters.Add(new CodeParameterDeclarationExpression(typeof(System.Exception), "exception")); cc.Parameters.Add(new CodeParameterDeclarationExpression(typeof(bool), "cancelled")); cc.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "userState")); cc.BaseConstructorArgs.Add(new CodeVariableReferenceExpression("exception")); cc.BaseConstructorArgs.Add(new CodeVariableReferenceExpression("cancelled")); cc.BaseConstructorArgs.Add(new CodeVariableReferenceExpression("userState")); CodeExpression thisResults = new CodeFieldReferenceExpression(ethis, "results"); cc.Statements.Add(new CodeAssignStatement(thisResults, new CodeVariableReferenceExpression("results"))); argsClass.Members.Add(cc); int ind = 0; if (method.ReturnType.BaseType != "System.Void") { argsClass.Members.Add(CreateArgsProperty(method.ReturnType, "Result", ind++)); } foreach (CodeParameterDeclarationExpression par in method.Parameters) { if (par.Direction == FieldDirection.Out || par.Direction == FieldDirection.Ref) { argsClass.Members.Add(CreateArgsProperty(par.Type, par.Name, ind++)); } } bool needsArgsClass = (ind > 0); if (needsArgsClass) { asyncTypes.Add(argsClass); } else { argsClassName = "System.ComponentModel.AsyncCompletedEventArgs"; } // Event delegate type CodeTypeDelegate delegateType = new CodeTypeDelegate(messageName + "CompletedEventHandler"); delegateType.Attributes |= MemberAttributes.Public; delegateType.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "sender")); delegateType.Parameters.Add(new CodeParameterDeclarationExpression(argsClassName, "args")); // Event member CodeMemberEvent codeEvent = new CodeMemberEvent(); codeEvent.Attributes = codeEvent.Attributes & ~MemberAttributes.AccessMask | MemberAttributes.Public; codeEvent.Name = messageName + "Completed"; codeEvent.Type = new CodeTypeReference(delegateType.Name); CodeTypeDeclaration.Members.Add(codeEvent); // Async method (without user state param) CodeMemberMethod am = new CodeMemberMethod(); am.Attributes = MemberAttributes.Public | MemberAttributes.Final; am.Name = method.Name + "Async"; am.ReturnType = new CodeTypeReference(typeof(void)); CodeMethodInvokeExpression inv; inv = new CodeMethodInvokeExpression(ethis, am.Name); am.Statements.Add(inv); // On...Completed method CodeMemberMethod onCompleted = new CodeMemberMethod(); onCompleted.Name = "On" + messageName + "Completed"; onCompleted.Attributes = MemberAttributes.Private | MemberAttributes.Final; onCompleted.ReturnType = new CodeTypeReference(typeof(void)); onCompleted.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "arg")); CodeConditionStatement anIf = new CodeConditionStatement(); CodeExpression eventField = new CodeEventReferenceExpression(ethis, codeEvent.Name); anIf.Condition = new CodeBinaryOperatorExpression(eventField, CodeBinaryOperatorType.IdentityInequality, enull); CodeExpression castedArg = new CodeCastExpression(typeof(System.Web.Services.Protocols.InvokeCompletedEventArgs), new CodeVariableReferenceExpression("arg")); CodeStatement invokeArgs = new CodeVariableDeclarationStatement(typeof(System.Web.Services.Protocols.InvokeCompletedEventArgs), "invokeArgs", castedArg); anIf.TrueStatements.Add(invokeArgs); CodeDelegateInvokeExpression delegateInvoke = new CodeDelegateInvokeExpression(); delegateInvoke.TargetObject = eventField; delegateInvoke.Parameters.Add(ethis); CodeObjectCreateExpression argsInstance = new CodeObjectCreateExpression(argsClassName); CodeExpression invokeArgsVar = new CodeVariableReferenceExpression("invokeArgs"); if (needsArgsClass) { argsInstance.Parameters.Add(new CodeFieldReferenceExpression(invokeArgsVar, "Results")); } argsInstance.Parameters.Add(new CodeFieldReferenceExpression(invokeArgsVar, "Error")); argsInstance.Parameters.Add(new CodeFieldReferenceExpression(invokeArgsVar, "Cancelled")); argsInstance.Parameters.Add(new CodeFieldReferenceExpression(invokeArgsVar, "UserState")); delegateInvoke.Parameters.Add(argsInstance); anIf.TrueStatements.Add(delegateInvoke); onCompleted.Statements.Add(anIf); // Async method CodeMemberMethod asyncMethod = new CodeMemberMethod(); asyncMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final; asyncMethod.Name = method.Name + "Async"; asyncMethod.ReturnType = new CodeTypeReference(typeof(void)); CodeExpression delegateField = new CodeFieldReferenceExpression(ethis, codeField.Name); anIf = new CodeConditionStatement(); anIf.Condition = new CodeBinaryOperatorExpression(delegateField, CodeBinaryOperatorType.IdentityEquality, enull);; CodeExpression delegateRef = new CodeMethodReferenceExpression(ethis, onCompleted.Name); CodeExpression newDelegate = new CodeObjectCreateExpression(typeof(System.Threading.SendOrPostCallback), delegateRef); CodeAssignStatement cas = new CodeAssignStatement(delegateField, newDelegate); anIf.TrueStatements.Add(cas); asyncMethod.Statements.Add(anIf); CodeArrayCreateExpression paramsArray = new CodeArrayCreateExpression(typeof(object)); // Assign parameters CodeIdentifiers paramsIds = new CodeIdentifiers(); foreach (CodeParameterDeclarationExpression par in method.Parameters) { paramsIds.Add(par.Name, null); if (par.Direction == FieldDirection.In || par.Direction == FieldDirection.Ref) { CodeParameterDeclarationExpression inpar = new CodeParameterDeclarationExpression(par.Type, par.Name); am.Parameters.Add(inpar); asyncMethod.Parameters.Add(inpar); inv.Parameters.Add(new CodeVariableReferenceExpression(par.Name)); paramsArray.Initializers.Add(new CodeVariableReferenceExpression(par.Name)); } } inv.Parameters.Add(enull); string userStateName = paramsIds.AddUnique("userState", null); asyncMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), userStateName)); CodeExpression userStateVar = new CodeVariableReferenceExpression(userStateName); asyncMethod.Statements.Add(BuildInvokeAsync(messageName, paramsArray, delegateField, userStateVar)); CodeTypeDeclaration.Members.Add(am); CodeTypeDeclaration.Members.Add(asyncMethod); CodeTypeDeclaration.Members.Add(onCompleted); asyncTypes.Add(delegateType); }
void ImportBinding(ServiceDescription desc, Service service, TypeStubInfo typeInfo, string url, BindingInfo binfo) { port = new Port(); port.Name = portNames.AddUnique(binfo.Name, port); bool bindingFull = true; if (binfo.Namespace != desc.TargetNamespace) { if (binfo.Location == null || binfo.Location == string.Empty) { ServiceDescription newDesc = new ServiceDescription(); newDesc.TargetNamespace = binfo.Namespace; newDesc.Name = binfo.Name; bindingFull = ImportBindingContent(newDesc, typeInfo, url, binfo); if (bindingFull) { int id = ServiceDescriptions.Add(newDesc); AddImport(desc, binfo.Namespace, GetWsdlUrl(url, id)); } } else { AddImport(desc, binfo.Namespace, binfo.Location); bindingFull = true; } } else { bindingFull = ImportBindingContent(desc, typeInfo, url, binfo); } if (bindingFull) { port.Binding = new XmlQualifiedName(binding.Name, binfo.Namespace); int n = 0; string name = binfo.Name; bool found; do { found = false; foreach (Port p in service.Ports) { if (p.Name == name) { found = true; n++; name = binfo.Name + n; break; } } }while (found); port.Name = name; service.Ports.Add(port); } #if NET_2_0 if (binfo.WebServiceBindingAttribute != null && binfo.WebServiceBindingAttribute.ConformsTo != WsiProfiles.None && String.IsNullOrEmpty(binfo.WebServiceBindingAttribute.Name)) { BasicProfileViolationCollection violations = new BasicProfileViolationCollection(); desc.Types.Schemas.Add(Schemas); ServiceDescriptionCollection col = new ServiceDescriptionCollection(); col.Add(desc); ConformanceCheckContext ctx = new ConformanceCheckContext(col, violations); ctx.ServiceDescription = desc; ConformanceChecker[] checkers = WebServicesInteroperability.GetCheckers(binfo.WebServiceBindingAttribute.ConformsTo); foreach (ConformanceChecker checker in checkers) { ctx.Checker = checker; WebServicesInteroperability.Check(ctx, checker, binding); if (violations.Count > 0) { throw new InvalidOperationException(violations [0].ToString()); } } } #endif }
internal static CodeTypeDeclaration CreateArgsClass(string name, string[] paramTypes, string[] paramNames, bool isPartial) { CodeTypeDeclaration codeClass = new CodeTypeDeclaration(name); codeClass.CustomAttributes.Add(GeneratedCodeAttribute); // Add [DebuggerStepThrough] codeClass.CustomAttributes.Add(new CodeAttributeDeclaration(typeof(DebuggerStepThroughAttribute).FullName)); // Add [DesignerCategory("code")] codeClass.CustomAttributes.Add(new CodeAttributeDeclaration(typeof(DesignerCategoryAttribute).FullName, new CodeAttributeArgument[] { new CodeAttributeArgument(new CodePrimitiveExpression("code")) })); codeClass.IsPartial = isPartial; codeClass.BaseTypes.Add(new CodeTypeReference(typeof(AsyncCompletedEventArgs))); CodeIdentifiers identifiers = new CodeIdentifiers(); identifiers.AddUnique("Error", "Error"); identifiers.AddUnique("Cancelled", "Cancelled"); identifiers.AddUnique("UserState", "UserState"); for (int i = 0; i < paramNames.Length; i++) { if (paramNames[i] != null) { identifiers.AddUnique(paramNames[i], paramNames[i]); } } string results = identifiers.AddUnique("results", "results"); CodeMemberField data = new CodeMemberField(typeof(object[]), results); codeClass.Members.Add(data); CodeConstructor ctor = new CodeConstructor(); ctor.Attributes = (ctor.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Assembly; CodeParameterDeclarationExpression param = new CodeParameterDeclarationExpression(typeof(object[]), results); ctor.Parameters.Add(param); ctor.Parameters.Add(new CodeParameterDeclarationExpression(typeof(Exception), "exception")); ctor.Parameters.Add(new CodeParameterDeclarationExpression(typeof(bool), "cancelled")); ctor.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "userState")); ctor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("exception")); ctor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("cancelled")); ctor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("userState")); ctor.Statements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), data.Name), new CodeArgumentReferenceExpression(results))); codeClass.Members.Add(ctor); int index = 0; for (int i = 0; i < paramNames.Length; i++) { if (paramNames[i] != null) { codeClass.Members.Add(CreatePropertyDeclaration(data, paramNames[i], paramTypes[i], index++)); } } codeClass.Comments.Add(new CodeCommentStatement(Res.GetString(Res.CodeRemarks), true)); return(codeClass); }
void ImportHeader(CodeMemberMethod method, SoapHeaderBinding hb, SoapHeaderDirection direction) { Message msg = ServiceDescriptions.GetMessage(hb.Message); if (msg == null) { throw new InvalidOperationException("Message " + hb.Message + " not found"); } MessagePart part = msg.Parts [hb.Part]; if (part == null) { throw new InvalidOperationException("Message part " + hb.Part + " not found in message " + hb.Message); } XmlTypeMapping map; string hname; if (hb.Use == SoapBindingUse.Literal) { map = xmlImporter.ImportDerivedTypeMapping(part.Element, typeof(SoapHeader)); hname = part.Element.Name; xmlExporter.ExportTypeMapping(map); } else { map = soapImporter.ImportDerivedTypeMapping(part.Type, typeof(SoapHeader), true); hname = part.Type.Name; soapExporter.ExportTypeMapping(map); } string varName = headerVariables [map] as string; if (varName == null) { if (hname == map.TypeName) { varName = memberIds.AddUnique(CodeIdentifier.MakeValid(hname + "Value"), hb); } else { varName = memberIds.AddUnique(CodeIdentifier.MakeValid(hname), hb); } #if NET_2_0 string propName = varName; varName = varName + "Field"; #endif headerVariables.Add(map, varName); CodeMemberField codeField = new CodeMemberField(map.TypeFullName, varName); CodeTypeDeclaration.Members.Add(codeField); #if NET_2_0 codeField.Attributes = MemberAttributes.Private; CodeMemberProperty codeProperty = new CodeMemberProperty(); codeProperty.Name = propName; codeProperty.Type = new CodeTypeReference(map.TypeFullName); codeProperty.Attributes = MemberAttributes.Public | MemberAttributes.Final; codeProperty.HasGet = codeProperty.HasSet = true; CodeExpression ce = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), varName); codeProperty.SetStatements.Add(new CodeAssignStatement(ce, new CodePropertySetValueReferenceExpression())); codeProperty.GetStatements.Add(new CodeMethodReturnStatement(ce)); CodeTypeDeclaration.Members.Add(codeProperty); #else codeField.Attributes = MemberAttributes.Public; #endif } CodeAttributeDeclaration att = new CodeAttributeDeclaration("System.Web.Services.Protocols.SoapHeaderAttribute"); att.Arguments.Add(GetArg(varName)); #if ONLY_1_0 att.Arguments.Add(GetArg("Required", false)); #endif if (direction != SoapHeaderDirection.In) { att.Arguments.Add(GetEnumArg("Direction", "System.Web.Services.Protocols.SoapHeaderDirection", direction.ToString())); } AddCustomAttribute(method, att, true); }
CodeMemberMethod GenerateMethod(CodeIdentifiers memberIds, SoapOperationBinding soapOper, SoapBodyBinding bodyBinding, XmlMembersMapping inputMembers, XmlMembersMapping outputMembers) { CodeIdentifiers pids = new CodeIdentifiers(); CodeMemberMethod method = new CodeMemberMethod(); CodeMemberMethod methodBegin = new CodeMemberMethod(); CodeMemberMethod methodEnd = new CodeMemberMethod(); method.Attributes = MemberAttributes.Public | MemberAttributes.Final; methodBegin.Attributes = MemberAttributes.Public | MemberAttributes.Final; methodEnd.Attributes = MemberAttributes.Public | MemberAttributes.Final; SoapBindingStyle style = soapOper.Style != SoapBindingStyle.Default ? soapOper.Style : soapBinding.Style; // Find unique names for temporary variables for (int n = 0; n < inputMembers.Count; n++) { pids.AddUnique(inputMembers[n].MemberName, inputMembers[n]); } if (outputMembers != null) { for (int n = 0; n < outputMembers.Count; n++) { pids.AddUnique(outputMembers[n].MemberName, outputMembers[n]); } } string varAsyncResult = pids.AddUnique("asyncResult", "asyncResult"); string varResults = pids.AddUnique("results", "results"); string varCallback = pids.AddUnique("callback", "callback"); string varAsyncState = pids.AddUnique("asyncState", "asyncState"); string messageName = memberIds.AddUnique(CodeIdentifier.MakeValid(Operation.Name), method); method.Name = CodeIdentifier.MakeValid(Operation.Name); if (method.Name == ClassName) { method.Name += "1"; } methodBegin.Name = memberIds.AddUnique(CodeIdentifier.MakeValid("Begin" + method.Name), method); methodEnd.Name = memberIds.AddUnique(CodeIdentifier.MakeValid("End" + method.Name), method); method.ReturnType = new CodeTypeReference(typeof(void)); methodEnd.ReturnType = new CodeTypeReference(typeof(void)); methodEnd.Parameters.Add(new CodeParameterDeclarationExpression(typeof(IAsyncResult), varAsyncResult)); CodeExpression[] paramArray = new CodeExpression [inputMembers.Count]; CodeParameterDeclarationExpression[] outParams = new CodeParameterDeclarationExpression [outputMembers != null ? outputMembers.Count : 0]; for (int n = 0; n < inputMembers.Count; n++) { CodeParameterDeclarationExpression param = GenerateParameter(inputMembers[n], FieldDirection.In); method.Parameters.Add(param); GenerateMemberAttributes(inputMembers, inputMembers[n], bodyBinding.Use, param); methodBegin.Parameters.Add(GenerateParameter(inputMembers[n], FieldDirection.In)); paramArray [n] = new CodeVariableReferenceExpression(param.Name); } if (outputMembers != null) { bool hasReturn = false; for (int n = 0; n < outputMembers.Count; n++) { CodeParameterDeclarationExpression cpd = GenerateParameter(outputMembers[n], FieldDirection.Out); outParams [n] = cpd; bool found = false; foreach (CodeParameterDeclarationExpression ip in method.Parameters) { if (ip.Name == cpd.Name && ip.Type.BaseType == cpd.Type.BaseType) { ip.Direction = FieldDirection.Ref; methodEnd.Parameters.Add(GenerateParameter(outputMembers[n], FieldDirection.Out)); found = true; break; } } if (found) { continue; } if (!hasReturn) { hasReturn = true; method.ReturnType = cpd.Type; methodEnd.ReturnType = cpd.Type; GenerateReturnAttributes(outputMembers, outputMembers[n], bodyBinding.Use, method); outParams [n] = null; continue; } method.Parameters.Add(cpd); GenerateMemberAttributes(outputMembers, outputMembers[n], bodyBinding.Use, cpd); methodEnd.Parameters.Add(GenerateParameter(outputMembers[n], FieldDirection.Out)); } } methodBegin.Parameters.Add(new CodeParameterDeclarationExpression(typeof(AsyncCallback), varCallback)); methodBegin.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), varAsyncState)); methodBegin.ReturnType = new CodeTypeReference(typeof(IAsyncResult)); // Array of input parameters CodeArrayCreateExpression methodParams; if (paramArray.Length > 0) { methodParams = new CodeArrayCreateExpression(typeof(object), paramArray); } else { methodParams = new CodeArrayCreateExpression(typeof(object), 0); } // Assignment of output parameters CodeStatementCollection outAssign = new CodeStatementCollection(); CodeVariableReferenceExpression arrVar = new CodeVariableReferenceExpression(varResults); for (int n = 0; n < outParams.Length; n++) { CodeExpression index = new CodePrimitiveExpression(n); if (outParams[n] == null) { CodeExpression res = new CodeCastExpression(method.ReturnType, new CodeArrayIndexerExpression(arrVar, index)); outAssign.Add(new CodeMethodReturnStatement(res)); } else { CodeExpression res = new CodeCastExpression(outParams[n].Type, new CodeArrayIndexerExpression(arrVar, index)); CodeExpression var = new CodeVariableReferenceExpression(outParams[n].Name); outAssign.Insert(0, new CodeAssignStatement(var, res)); } } if (Style == ServiceDescriptionImportStyle.Client) { // Invoke call CodeThisReferenceExpression ethis = new CodeThisReferenceExpression(); CodePrimitiveExpression varMsgName = new CodePrimitiveExpression(messageName); CodeMethodInvokeExpression inv; CodeVariableDeclarationStatement dec; inv = new CodeMethodInvokeExpression(ethis, "Invoke", varMsgName, methodParams); if (outputMembers != null && outputMembers.Count > 0) { dec = new CodeVariableDeclarationStatement(typeof(object[]), varResults, inv); method.Statements.Add(dec); method.Statements.AddRange(outAssign); } else { method.Statements.Add(inv); } // Begin Invoke Call CodeExpression expCallb = new CodeVariableReferenceExpression(varCallback); CodeExpression expAsyncs = new CodeVariableReferenceExpression(varAsyncState); inv = new CodeMethodInvokeExpression(ethis, "BeginInvoke", varMsgName, methodParams, expCallb, expAsyncs); methodBegin.Statements.Add(new CodeMethodReturnStatement(inv)); // End Invoke call CodeExpression varAsyncr = new CodeVariableReferenceExpression(varAsyncResult); inv = new CodeMethodInvokeExpression(ethis, "EndInvoke", varAsyncr); if (outputMembers != null && outputMembers.Count > 0) { dec = new CodeVariableDeclarationStatement(typeof(object[]), varResults, inv); methodEnd.Statements.Add(dec); methodEnd.Statements.AddRange(outAssign); } else { methodEnd.Statements.Add(inv); } } else { method.Attributes = MemberAttributes.Public | MemberAttributes.Abstract; } // Attributes ImportHeaders(method); CodeAttributeDeclaration att = new CodeAttributeDeclaration("System.Web.Services.WebMethodAttribute"); if (messageName != method.Name) { att.Arguments.Add(GetArg("MessageName", messageName)); } AddCustomAttribute(method, att, (Style == ServiceDescriptionImportStyle.Server)); if (style == SoapBindingStyle.Rpc) { att = new CodeAttributeDeclaration("System.Web.Services.Protocols.SoapRpcMethodAttribute"); att.Arguments.Add(GetArg(soapOper.SoapAction)); if (inputMembers.ElementName != method.Name) { att.Arguments.Add(GetArg("RequestElementName", inputMembers.ElementName)); } if (outputMembers != null && outputMembers.ElementName != (method.Name + "Response")) { att.Arguments.Add(GetArg("ResponseElementName", outputMembers.ElementName)); } att.Arguments.Add(GetArg("RequestNamespace", inputMembers.Namespace)); if (outputMembers != null) { att.Arguments.Add(GetArg("ResponseNamespace", outputMembers.Namespace)); } if (outputMembers == null) { att.Arguments.Add(GetArg("OneWay", true)); } } else { if (outputMembers != null && (inputMembers.ElementName == "" && outputMembers.ElementName != "" || inputMembers.ElementName != "" && outputMembers.ElementName == "")) { throw new InvalidOperationException("Parameter style is not the same for the input message and output message"); } att = new CodeAttributeDeclaration("System.Web.Services.Protocols.SoapDocumentMethodAttribute"); att.Arguments.Add(GetArg(soapOper.SoapAction)); if (inputMembers.ElementName != "") { if (inputMembers.ElementName != method.Name) { att.Arguments.Add(GetArg("RequestElementName", inputMembers.ElementName)); } if (outputMembers != null && outputMembers.ElementName != (method.Name + "Response")) { att.Arguments.Add(GetArg("ResponseElementName", outputMembers.ElementName)); } att.Arguments.Add(GetArg("RequestNamespace", inputMembers.Namespace)); if (outputMembers != null) { att.Arguments.Add(GetArg("ResponseNamespace", outputMembers.Namespace)); } att.Arguments.Add(GetEnumArg("ParameterStyle", "System.Web.Services.Protocols.SoapParameterStyle", "Wrapped")); } else { att.Arguments.Add(GetEnumArg("ParameterStyle", "System.Web.Services.Protocols.SoapParameterStyle", "Bare")); } if (outputMembers == null) { att.Arguments.Add(GetArg("OneWay", true)); } att.Arguments.Add(GetEnumArg("Use", "System.Web.Services.Description.SoapBindingUse", bodyBinding.Use.ToString())); } AddCustomAttribute(method, att, true); CodeTypeDeclaration.Members.Add(method); if (Style == ServiceDescriptionImportStyle.Client) { CodeTypeDeclaration.Members.Add(methodBegin); CodeTypeDeclaration.Members.Add(methodEnd); } return(method); }
void ReflectBinding(ReflectedBinding reflectedBinding) { string bindingName = reflectedBinding.bindingAttr.Name; string bindingNamespace = reflectedBinding.bindingAttr.Namespace; if (bindingName.Length == 0) { bindingName = Service.Name + ProtocolName; } if (bindingNamespace.Length == 0) { bindingNamespace = ServiceDescription.TargetNamespace; } if (reflectedBinding.bindingAttr.Location.Length > 0) { // If a URL is specified for the WSDL, file, then we just import the // binding from there instead of generating it in this WSDL file. portType = null; binding = null; } else { bindingServiceDescription = GetServiceDescription(bindingNamespace); CodeIdentifiers bindingNames = new CodeIdentifiers(); foreach (Binding b in bindingServiceDescription.Bindings) { bindingNames.AddReserved(b.Name); } bindingName = bindingNames.AddUnique(bindingName, binding); portType = new PortType(); binding = new Binding(); portType.Name = bindingName; binding.Name = bindingName; binding.Type = new XmlQualifiedName(portType.Name, bindingNamespace); bindingServiceDescription.Bindings.Add(binding); bindingServiceDescription.PortTypes.Add(portType); } if (portNames == null) { portNames = new CodeIdentifiers(); foreach (Port p in Service.Ports) { portNames.AddReserved(p.Name); } } port = new Port(); port.Binding = new XmlQualifiedName(bindingName, bindingNamespace); port.Name = portNames.AddUnique(bindingName, port); Service.Ports.Add(port); BeginClass(); foreach (LogicalMethodInfo method in reflectedBinding.methodList) { MoveToMethod(method); operation = new Operation(); operation.Name = method.Name; operation.Documentation = methodAttr.Description; operationBinding = new OperationBinding(); operationBinding.Name = operation.Name; inputMessage = null; outputMessage = null; headerMessages = null; if (ReflectMethod()) { if (inputMessage != null) { bindingServiceDescription.Messages.Add(inputMessage); } if (outputMessage != null) { bindingServiceDescription.Messages.Add(outputMessage); } if (headerMessages != null) { foreach (Message headerMessage in headerMessages) { bindingServiceDescription.Messages.Add(headerMessage); } } binding.Operations.Add(operationBinding); portType.Operations.Add(operation); } } EndClass(); }