2 // System.Web.Services.Description.ProtocolImporter.cs
5 // Tim Coleman (tim@timcoleman.com)
6 // Lluis Sanchez Gual (lluis@ximian.com)
8 // Copyright (C) Tim Coleman, 2002
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System.CodeDom.Compiler;
35 using System.Web.Services;
36 using System.Web.Services.Protocols;
37 using System.Xml.Serialization;
39 using System.Xml.Schema;
40 using System.Collections;
41 using System.Configuration;
43 namespace System.Web.Services.Description {
44 public abstract class ProtocolImporter {
50 CodeIdentifiers classNames;
51 CodeNamespace codeNamespace;
52 CodeTypeDeclaration codeTypeDeclaration;
56 OperationBinding operationBinding;
57 Message outputMessage;
61 ServiceDescriptionImportWarnings warnings = (ServiceDescriptionImportWarnings)0;
62 ServiceDescriptionImporter descriptionImporter;
64 XmlSchemas xmlSchemas;
65 XmlSchemas soapSchemas;
67 ArrayList asyncTypes = new ArrayList ();
73 protected ProtocolImporter ()
77 #endregion // Constructors
82 public XmlSchemas AbstractSchemas {
83 get { return descriptionImporter.Schemas; }
86 public Binding Binding {
87 get { return binding; }
90 public string ClassName {
91 get { return className; }
94 public CodeIdentifiers ClassNames {
95 get { return classNames; }
98 public CodeNamespace CodeNamespace {
99 get { return codeNamespace; }
102 public CodeTypeDeclaration CodeTypeDeclaration {
103 get { return codeTypeDeclaration; }
107 public XmlSchemas ConcreteSchemas {
108 get { return descriptionImporter.Schemas; }
111 public Message InputMessage {
112 get { return inputMessage; }
115 public string MethodName {
116 get { return methodName; }
119 public Operation Operation {
120 get { return operation; }
123 public OperationBinding OperationBinding {
124 get { return operationBinding; }
127 public Message OutputMessage {
128 get { return outputMessage; }
135 public PortType PortType {
136 get { return portType; }
139 public abstract string ProtocolName {
143 public XmlSchemas Schemas {
144 get { return descriptionImporter.Schemas; }
147 public Service Service {
148 get { return service; }
151 public ServiceDescriptionCollection ServiceDescriptions {
152 get { return descriptionImporter.ServiceDescriptions; }
155 public ServiceDescriptionImportStyle Style {
156 get { return descriptionImporter.Style; }
159 public ServiceDescriptionImportWarnings Warnings {
160 get { return warnings; }
161 set { warnings = value; }
164 internal ImportInfo ImportInfo
166 get { return iinfo; }
169 internal XmlSchemas LiteralSchemas
171 get { return xmlSchemas; }
174 internal XmlSchemas EncodedSchemas
176 get { return soapSchemas; }
179 internal CodeGenerationOptions CodeGenerationOptions {
180 get { return descriptionImporter.CodeGenerationOptions; }
183 internal CodeDomProvider CodeGenerator {
184 get { return descriptionImporter.CodeGenerator; }
187 internal ImportContext ImportContext {
188 get { return descriptionImporter.Context; }
191 #endregion // Properties
195 internal bool Import (ServiceDescriptionImporter descriptionImporter, CodeNamespace codeNamespace, ArrayList importInfo)
197 this.descriptionImporter = descriptionImporter;
198 this.classNames = new CodeIdentifiers();;
199 this.codeNamespace = codeNamespace;
201 warnings = (ServiceDescriptionImportWarnings) 0;
205 ClasifySchemas (importInfo);
209 foreach (ImportInfo info in importInfo)
211 foreach (Service service in info.ServiceDescription.Services)
213 this.service = service;
214 int bindingCount = 0;
215 foreach (Port port in service.Ports)
217 binding = ServiceDescriptions.GetBinding (port.Binding);
218 if (IsBindingSupported ()) bindingCount ++;
221 foreach (Port port in service.Ports)
225 binding = ServiceDescriptions.GetBinding (port.Binding);
226 if (!IsBindingSupported ()) continue;
229 ImportPortBinding (bindingCount > 1);
236 // Looks like MS.NET generates classes for all bindings if
237 // no services are present
239 foreach (ImportInfo info in importInfo)
242 foreach (Binding b in info.ServiceDescription.Bindings)
247 if (!IsBindingSupported ()) continue;
249 ImportPortBinding (true);
256 if (!found) warnings = ServiceDescriptionImportWarnings.NoCodeGenerated;
260 void ImportPortBinding (bool multipleBindings)
263 if (multipleBindings) className = binding.Name;
264 else className = service.Name;
267 className = binding.Name;
269 className = classNames.AddUnique (CodeIdentifier.MakeValid (className), port);
270 className = className.Replace ("_x0020_", ""); // MS.NET seems to do this
274 portType = ServiceDescriptions.GetPortType (binding.Type);
275 if (portType == null) throw new Exception ("Port type not found: " + binding.Type);
277 CodeTypeDeclaration codeClass = BeginClass ();
278 codeTypeDeclaration = codeClass;
279 AddCodeType (codeClass, port != null ? port.Documentation : null);
280 codeClass.Attributes = MemberAttributes.Public;
282 if (service != null && service.Documentation != null && service.Documentation != "")
283 AddComments (codeClass, service.Documentation);
285 if (Style == ServiceDescriptionImportStyle.Client) {
286 CodeAttributeDeclaration att = new CodeAttributeDeclaration ("System.Diagnostics.DebuggerStepThroughAttribute");
287 AddCustomAttribute (codeClass, att, true);
289 att = new CodeAttributeDeclaration ("System.ComponentModel.DesignerCategoryAttribute");
290 att.Arguments.Add (GetArg ("code"));
291 AddCustomAttribute (codeClass, att, true);
294 codeClass.TypeAttributes = System.Reflection.TypeAttributes.Abstract | System.Reflection.TypeAttributes.Public;
296 if (binding.Operations.Count == 0) {
297 warnings |= ServiceDescriptionImportWarnings.NoMethodsGenerated;
301 foreach (OperationBinding oper in binding.Operations)
303 operationBinding = oper;
304 operation = FindPortOperation ();
305 if (operation == null)
306 throw new Exception ("Operation " + operationBinding.Name + " not found in portType " + PortType.Name);
309 outputMessage = null;
311 foreach (OperationMessage omsg in operation.Messages)
313 Message msg = ServiceDescriptions.GetMessage (omsg.Message);
314 if (msg == null) throw new Exception ("Message not found: " + omsg.Message);
316 if (omsg is OperationInput)
322 CodeMemberMethod method = GenerateMethod ();
326 methodName = method.Name;
327 if (operation.Documentation != null && operation.Documentation != "")
328 AddComments (method, operation.Documentation);
329 if (Style == ServiceDescriptionImportStyle.Client)
330 AddAsyncMembers (method.Name, method);
334 if (Style == ServiceDescriptionImportStyle.Client)
339 catch (InvalidOperationException ex)
341 warnings |= ServiceDescriptionImportWarnings.NoCodeGenerated;
342 UnsupportedBindingWarning (ex.Message);
346 Operation FindPortOperation ()
348 string inMessage = null;
349 string outMessage = null;
352 if (operationBinding.Input == null) throw new InvalidOperationException ("Input operation binding not found");
353 inMessage = (operationBinding.Input.Name != null) ? operationBinding.Input.Name : operationBinding.Name;
355 if (operationBinding.Output != null) {
356 outMessage = (operationBinding.Output.Name != null) ? operationBinding.Output.Name : operationBinding.Name;
360 string operName = operationBinding.Name;
362 Operation foundOper = null;
363 foreach (Operation oper in PortType.Operations)
365 if (oper.Name == operName)
368 foreach (OperationMessage omsg in oper.Messages)
370 if (omsg is OperationInput && GetOperMessageName (omsg, operName) == inMessage) hits++;
371 if (omsg is OperationOutput && GetOperMessageName (omsg, operName) == outMessage) hits++;
373 if (hits == numMsg) return oper;
380 string GetOperMessageName (OperationMessage msg, string operName)
382 if (msg.Name == null) return operName;
383 else return msg.Name;
386 internal void GenerateServiceUrl (string location, CodeStatementCollection stms)
388 if (ImportInfo.AppSettingUrlKey == null || ImportInfo.AppSettingUrlKey == string.Empty) {
389 if (location != null) {
390 CodeExpression ce = new CodeFieldReferenceExpression (new CodeThisReferenceExpression(), "Url");
391 CodeAssignStatement cas = new CodeAssignStatement (ce, new CodePrimitiveExpression (location));
397 CodeExpression prop = new CodePropertyReferenceExpression (new CodeTypeReferenceExpression ("System.Configuration.ConfigurationSettings"), "AppSettings");
398 prop = new CodeIndexerExpression (prop, new CodePrimitiveExpression (ImportInfo.AppSettingUrlKey));
399 stms.Add (new CodeVariableDeclarationStatement (typeof(string), "urlSetting", prop));
401 CodeExpression urlSetting = new CodeVariableReferenceExpression ("urlSetting");
402 CodeExpression thisUrl = new CodeFieldReferenceExpression (new CodeThisReferenceExpression(), "Url");
404 CodeStatement[] trueStms = new CodeStatement [1];
405 CodeExpression ce = urlSetting;
406 CodeExpression cond = new CodeBinaryOperatorExpression (urlSetting, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression (null));
408 if (ImportInfo.AppSettingBaseUrl != null)
409 ce = new CodeMethodInvokeExpression (new CodeTypeReferenceExpression (typeof(string)), "Concat", ce, new CodePrimitiveExpression (ImportInfo.AppSettingBaseUrl));
410 trueStms [0] = new CodeAssignStatement (thisUrl, ce);
412 if (location != null) {
413 CodeStatement[] falseStms = new CodeStatement [1];
414 falseStms [0] = new CodeAssignStatement (thisUrl, new CodePrimitiveExpression (location));
415 stms.Add (new CodeConditionStatement (cond, trueStms, falseStms));
418 stms.Add (new CodeConditionStatement (cond, trueStms));
422 void ClasifySchemas (ArrayList importInfo)
424 // I don't like this, but I could not find any other way of clasifying
425 // schemas between encoded and literal.
427 xmlSchemas = new XmlSchemas ();
428 soapSchemas = new XmlSchemas ();
430 foreach (ImportInfo info in importInfo)
432 foreach (Service service in info.ServiceDescription.Services)
434 foreach (Port port in service.Ports)
438 binding = ServiceDescriptions.GetBinding (port.Binding);
439 if (binding == null) continue;
440 portType = ServiceDescriptions.GetPortType (binding.Type);
441 if (portType == null) continue;
443 foreach (OperationBinding oper in binding.Operations)
445 operationBinding = oper;
446 operation = FindPortOperation ();
447 if (operation == null) continue;
449 foreach (OperationMessage omsg in operation.Messages)
451 Message msg = ServiceDescriptions.GetMessage (omsg.Message);
452 if (msg == null) continue;
454 if (omsg is OperationInput)
460 if (GetMessageEncoding (oper.Input) == SoapBindingUse.Encoded)
461 AddMessageSchema (soapSchemas, oper.Input, inputMessage);
463 AddMessageSchema (xmlSchemas, oper.Input, inputMessage);
465 if (oper.Output != null) {
466 if (GetMessageEncoding (oper.Output) == SoapBindingUse.Encoded)
467 AddMessageSchema (soapSchemas, oper.Output, outputMessage);
469 AddMessageSchema (xmlSchemas, oper.Output, outputMessage);
476 XmlSchemas defaultList = xmlSchemas;
478 if (xmlSchemas.Count == 0 && soapSchemas.Count > 0)
479 defaultList = soapSchemas;
481 // Schemas not referenced by any message
482 foreach (XmlSchema sc in Schemas)
484 if (!soapSchemas.Contains (sc) && !xmlSchemas.Contains (sc)) {
485 if (ImportsEncodedNamespace (sc))
486 soapSchemas.Add (sc);
488 defaultList.Add (sc);
493 void AddMessageSchema (XmlSchemas schemas, MessageBinding mb, Message msg)
495 foreach (MessagePart part in msg.Parts)
497 if (part.Element != XmlQualifiedName.Empty)
498 AddIncludingSchema (schemas, part.Element.Namespace);
499 else if (part.Type != XmlQualifiedName.Empty)
500 AddIncludingSchema (schemas, part.Type.Namespace);
502 SoapBodyBinding sbb = mb.Extensions.Find (typeof(SoapBodyBinding)) as SoapBodyBinding;
503 if (sbb != null) AddIncludingSchema (schemas, sbb.Namespace);
506 void AddIncludingSchema (XmlSchemas list, string ns)
508 foreach (XmlSchema sc in Schemas) {
509 if (sc.TargetNamespace == ns && !list.Contains (sc)) {
511 foreach (XmlSchemaObject ob in sc.Includes) {
512 XmlSchemaImport import = ob as XmlSchemaImport;
513 if (import != null) AddIncludingSchema (list, import.Namespace);
519 SoapBindingUse GetMessageEncoding (MessageBinding mb)
521 SoapBodyBinding sbb = mb.Extensions.Find (typeof(SoapBodyBinding)) as SoapBodyBinding;
524 if (mb is InputBinding) return SoapBindingUse.Encoded;
525 else return SoapBindingUse.Literal;
528 if (sbb.Use == SoapBindingUse.Encoded) return SoapBindingUse.Encoded;
530 return SoapBindingUse.Literal;
533 bool ImportsEncodedNamespace (XmlSchema sc)
535 foreach (XmlSchemaObject ob in sc.Includes)
537 XmlSchemaImport import = ob as XmlSchemaImport;
540 if (import.Namespace == Soap11BindingExtensionReflector.EncodingNamespace
541 || import.Namespace == Soap12BindingExtensionReflector.EncodingNamespace)
548 void AddAsyncTypes ()
550 foreach (CodeTypeDeclaration type in asyncTypes)
551 codeNamespace.Types.Add (type);
555 void AddAsyncMembers (string messageName, CodeMemberMethod method)
557 CodeThisReferenceExpression ethis = new CodeThisReferenceExpression();
558 CodePrimitiveExpression enull = new CodePrimitiveExpression (null);
560 CodeMemberField codeField = new CodeMemberField (typeof(System.Threading.SendOrPostCallback), messageName + "OperationCompleted");
561 codeField.Attributes = MemberAttributes.Private;
562 CodeTypeDeclaration.Members.Add (codeField);
564 // Event arguments class
566 string argsClassName = classNames.AddUnique (messageName + "CompletedEventArgs", null);
567 CodeTypeDeclaration argsClass = new CodeTypeDeclaration (argsClassName);
568 argsClass.Attributes |= MemberAttributes.Public;
569 argsClass.IsPartial = true;
570 argsClass.BaseTypes.Add (new CodeTypeReference ("System.ComponentModel.AsyncCompletedEventArgs"));
572 CodeMemberField resultsField = new CodeMemberField (typeof(object[]), "results");
573 resultsField.Attributes = MemberAttributes.Private;
574 argsClass.Members.Add (resultsField);
576 CodeConstructor cc = new CodeConstructor ();
577 cc.Attributes = MemberAttributes.Assembly;
578 cc.Parameters.Add (new CodeParameterDeclarationExpression (typeof(object[]), "results"));
579 cc.Parameters.Add (new CodeParameterDeclarationExpression (typeof(System.Exception), "exception"));
580 cc.Parameters.Add (new CodeParameterDeclarationExpression (typeof(bool), "cancelled"));
581 cc.Parameters.Add (new CodeParameterDeclarationExpression (typeof(object), "userState"));
582 cc.BaseConstructorArgs.Add (new CodeVariableReferenceExpression ("exception"));
583 cc.BaseConstructorArgs.Add (new CodeVariableReferenceExpression ("cancelled"));
584 cc.BaseConstructorArgs.Add (new CodeVariableReferenceExpression ("userState"));
585 CodeExpression thisResults = new CodeFieldReferenceExpression (ethis, "results");
586 cc.Statements.Add (new CodeAssignStatement (thisResults, new CodeVariableReferenceExpression ("results")));
587 argsClass.Members.Add (cc);
591 if (method.ReturnType.BaseType != "System.Void")
592 argsClass.Members.Add (CreateArgsProperty (method.ReturnType, "Result", ind++));
594 foreach (CodeParameterDeclarationExpression par in method.Parameters)
596 if (par.Direction == FieldDirection.Out || par.Direction == FieldDirection.Ref)
597 argsClass.Members.Add (CreateArgsProperty (par.Type, par.Name, ind++));
600 bool needsArgsClass = (ind > 0);
602 asyncTypes.Add (argsClass);
604 argsClassName = "System.ComponentModel.AsyncCompletedEventArgs";
606 // Event delegate type
608 CodeTypeDelegate delegateType = new CodeTypeDelegate (messageName + "CompletedEventHandler");
609 delegateType.Attributes |= MemberAttributes.Public;
610 delegateType.Parameters.Add (new CodeParameterDeclarationExpression (typeof(object), "sender"));
611 delegateType.Parameters.Add (new CodeParameterDeclarationExpression (argsClassName, "args"));
615 CodeMemberEvent codeEvent = new CodeMemberEvent ();
616 codeEvent.Attributes = codeEvent.Attributes & ~MemberAttributes.AccessMask | MemberAttributes.Public;
617 codeEvent.Name = messageName + "Completed";
618 codeEvent.Type = new CodeTypeReference (delegateType.Name);
619 CodeTypeDeclaration.Members.Add (codeEvent);
621 // Async method (without user state param)
623 CodeMemberMethod am = new CodeMemberMethod ();
624 am.Attributes = MemberAttributes.Public | MemberAttributes.Final;
625 am.Name = method.Name + "Async";
626 am.ReturnType = new CodeTypeReference (typeof(void));
627 CodeMethodInvokeExpression inv;
628 inv = new CodeMethodInvokeExpression (ethis, am.Name);
629 am.Statements.Add (inv);
631 // On...Completed method
633 CodeMemberMethod onCompleted = new CodeMemberMethod ();
634 onCompleted.Name = "On" + messageName + "Completed";
635 onCompleted.Attributes = MemberAttributes.Private | MemberAttributes.Final;
636 onCompleted.ReturnType = new CodeTypeReference (typeof(void));
637 onCompleted.Parameters.Add (new CodeParameterDeclarationExpression (typeof(object), "arg"));
639 CodeConditionStatement anIf = new CodeConditionStatement ();
641 CodeExpression eventField = new CodeEventReferenceExpression (ethis, codeEvent.Name);
642 anIf.Condition = new CodeBinaryOperatorExpression (eventField, CodeBinaryOperatorType.IdentityInequality, enull);
643 CodeExpression castedArg = new CodeCastExpression (typeof(System.Web.Services.Protocols.InvokeCompletedEventArgs), new CodeVariableReferenceExpression ("arg"));
644 CodeStatement invokeArgs = new CodeVariableDeclarationStatement (typeof(System.Web.Services.Protocols.InvokeCompletedEventArgs), "invokeArgs", castedArg);
645 anIf.TrueStatements.Add (invokeArgs);
647 CodeDelegateInvokeExpression delegateInvoke = new CodeDelegateInvokeExpression ();
648 delegateInvoke.TargetObject = eventField;
649 delegateInvoke.Parameters.Add (ethis);
650 CodeObjectCreateExpression argsInstance = new CodeObjectCreateExpression (argsClassName);
651 CodeExpression invokeArgsVar = new CodeVariableReferenceExpression ("invokeArgs");
652 if (needsArgsClass) argsInstance.Parameters.Add (new CodeFieldReferenceExpression (invokeArgsVar, "Results"));
653 argsInstance.Parameters.Add (new CodeFieldReferenceExpression (invokeArgsVar, "Error"));
654 argsInstance.Parameters.Add (new CodeFieldReferenceExpression (invokeArgsVar, "Cancelled"));
655 argsInstance.Parameters.Add (new CodeFieldReferenceExpression (invokeArgsVar, "UserState"));
656 delegateInvoke.Parameters.Add (argsInstance);
657 anIf.TrueStatements.Add (delegateInvoke);
659 onCompleted.Statements.Add (anIf);
663 CodeMemberMethod asyncMethod = new CodeMemberMethod ();
664 asyncMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final;
665 asyncMethod.Name = method.Name + "Async";
666 asyncMethod.ReturnType = new CodeTypeReference (typeof(void));
668 CodeExpression delegateField = new CodeFieldReferenceExpression (ethis, codeField.Name);
669 anIf = new CodeConditionStatement ();
670 anIf.Condition = new CodeBinaryOperatorExpression (delegateField, CodeBinaryOperatorType.IdentityEquality, enull);;
671 CodeExpression delegateRef = new CodeMethodReferenceExpression (ethis, onCompleted.Name);
672 CodeExpression newDelegate = new CodeObjectCreateExpression (typeof(System.Threading.SendOrPostCallback), delegateRef);
673 CodeAssignStatement cas = new CodeAssignStatement (delegateField, newDelegate);
674 anIf.TrueStatements.Add (cas);
675 asyncMethod.Statements.Add (anIf);
677 CodeArrayCreateExpression paramsArray = new CodeArrayCreateExpression (typeof(object));
681 CodeIdentifiers paramsIds = new CodeIdentifiers ();
683 foreach (CodeParameterDeclarationExpression par in method.Parameters)
685 paramsIds.Add (par.Name, null);
686 if (par.Direction == FieldDirection.In || par.Direction == FieldDirection.Ref) {
687 CodeParameterDeclarationExpression inpar = new CodeParameterDeclarationExpression (par.Type, par.Name);
688 am.Parameters.Add (inpar);
689 asyncMethod.Parameters.Add (inpar);
690 inv.Parameters.Add (new CodeVariableReferenceExpression (par.Name));
691 paramsArray.Initializers.Add (new CodeVariableReferenceExpression (par.Name));
696 inv.Parameters.Add (enull);
698 string userStateName = paramsIds.AddUnique ("userState", null);
699 asyncMethod.Parameters.Add (new CodeParameterDeclarationExpression (typeof(object), userStateName));
701 CodeExpression userStateVar = new CodeVariableReferenceExpression (userStateName);
702 asyncMethod.Statements.Add (BuildInvokeAsync (messageName, paramsArray, delegateField, userStateVar));
704 CodeTypeDeclaration.Members.Add (am);
705 CodeTypeDeclaration.Members.Add (asyncMethod);
706 CodeTypeDeclaration.Members.Add (onCompleted);
708 asyncTypes.Add (delegateType);
711 CodeMemberProperty CreateArgsProperty (CodeTypeReference type, string name, int ind)
713 CodeMemberProperty prop = new CodeMemberProperty ();
714 prop.Attributes = MemberAttributes.Public | MemberAttributes.Final;
719 CodeThisReferenceExpression ethis = new CodeThisReferenceExpression();
720 CodeExpression thisResults = new CodeFieldReferenceExpression (ethis, "results");
721 prop.GetStatements.Add (new CodeMethodInvokeExpression (ethis, "RaiseExceptionIfNecessary"));
722 CodeArrayIndexerExpression arrValue = new CodeArrayIndexerExpression (thisResults, new CodePrimitiveExpression (ind));
723 CodeExpression retval = new CodeCastExpression (type, arrValue);
724 prop.GetStatements.Add (new CodeMethodReturnStatement (retval));
728 internal virtual CodeExpression BuildInvokeAsync (string messageName, CodeArrayCreateExpression paramsArray, CodeExpression delegateField, CodeExpression userStateVar)
730 CodeThisReferenceExpression ethis = new CodeThisReferenceExpression();
731 CodeMethodInvokeExpression inv2 = new CodeMethodInvokeExpression (ethis, "InvokeAsync");
732 inv2.Parameters.Add (new CodePrimitiveExpression (messageName));
733 inv2.Parameters.Add (paramsArray);
734 inv2.Parameters.Add (delegateField);
735 inv2.Parameters.Add (userStateVar);
740 public void AddExtensionWarningComments (CodeCommentStatementCollection comments, ServiceDescriptionFormatExtensionCollection extensions)
742 throw new NotImplementedException ();
745 protected abstract CodeTypeDeclaration BeginClass ();
747 protected virtual void BeginNamespace ()
751 protected virtual void EndClass ()
755 protected virtual void EndNamespace ()
759 protected abstract CodeMemberMethod GenerateMethod ();
760 protected abstract bool IsBindingSupported ();
761 protected abstract bool IsOperationFlowSupported (OperationFlow flow);
764 public Exception OperationBindingSyntaxException (string text)
766 throw new NotImplementedException ();
770 public Exception OperationSyntaxException (string text)
772 throw new NotImplementedException ();
775 public void UnsupportedBindingWarning (string text)
777 warnings |= ServiceDescriptionImportWarnings.UnsupportedBindingsIgnored;
778 AddGlobalComments ("WARNING: Could not generate proxy for binding " + binding.Name + ". " + text);
781 public void UnsupportedOperationBindingWarning (string text)
783 warnings |= ServiceDescriptionImportWarnings.UnsupportedOperationsIgnored;
784 AddGlobalComments ("WARNING: Could not generate operation binding " + OperationBinding.Name + ". " + text);
787 public void UnsupportedOperationWarning (string text)
789 warnings |= ServiceDescriptionImportWarnings.UnsupportedOperationsIgnored;
790 AddGlobalComments ("WARNING: Could not generate operation " + Operation.Name + ". " + text);
793 void AddGlobalComments (string comments)
795 codeNamespace.Comments.Add (new CodeCommentStatement (comments, false));
798 void AddComments (CodeTypeMember member, string comments)
800 if (comments == null || comments == "") member.Comments.Add (new CodeCommentStatement ("<remarks/>", true));
801 else member.Comments.Add (new CodeCommentStatement ("<remarks>\n" + comments + "\n</remarks>", true));
804 void AddCodeType (CodeTypeDeclaration type, string comments)
806 AddComments (type, comments);
807 codeNamespace.Types.Add (type);
810 internal void AddCustomAttribute (CodeTypeMember ctm, CodeAttributeDeclaration att, bool addIfNoParams)
812 if (att.Arguments.Count == 0 && !addIfNoParams) return;
814 if (ctm.CustomAttributes == null) ctm.CustomAttributes = new CodeAttributeDeclarationCollection ();
815 ctm.CustomAttributes.Add (att);
818 internal void AddCustomAttribute (CodeTypeMember ctm, string name, params CodeAttributeArgument[] args)
820 if (ctm.CustomAttributes == null) ctm.CustomAttributes = new CodeAttributeDeclarationCollection ();
821 ctm.CustomAttributes.Add (new CodeAttributeDeclaration (name, args));
824 internal CodeAttributeArgument GetArg (string name, object value)
826 return new CodeAttributeArgument (name, new CodePrimitiveExpression(value));
829 internal CodeAttributeArgument GetEnumArg (string name, string enumType, string enumValue)
831 return new CodeAttributeArgument (name, new CodeFieldReferenceExpression (new CodeTypeReferenceExpression(enumType), enumValue));
834 internal CodeAttributeArgument GetArg (object value)
836 return new CodeAttributeArgument (new CodePrimitiveExpression(value));
839 internal CodeAttributeArgument GetTypeArg (string name, string typeName)
841 return new CodeAttributeArgument (name, new CodeTypeOfExpression(typeName));