diff options
author | Atsushi Eno <atsushieno@gmail.com> | 2009-08-10 15:38:23 +0400 |
---|---|---|
committer | Atsushi Eno <atsushieno@gmail.com> | 2009-08-10 15:38:23 +0400 |
commit | aae196a7f4337cde9fe556ccd7015934e6cad5cb (patch) | |
tree | 8ac294f731725c7091b50e07b94660f3700b217d /mcs | |
parent | 693c94a2c60d54ac223cc9bd04ba5fcd8225b6ca (diff) |
2009-08-10 Atsushi Enomoto <atsushi@ximian.com>
* ServiceContractGenerator.cs,
OperationContractGenerationContext.cs : support extensions i.e.
IServiceContractGenerationExtension and IOperation...(ditto) .
svn path=/trunk/mcs/; revision=139630
Diffstat (limited to 'mcs')
3 files changed, 67 insertions, 34 deletions
diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Description/ChangeLog b/mcs/class/System.ServiceModel/System.ServiceModel.Description/ChangeLog index 90212204ba7..c4601a5d119 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Description/ChangeLog +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Description/ChangeLog @@ -1,5 +1,11 @@ 2009-08-10 Atsushi Enomoto <atsushi@ximian.com> + * ServiceContractGenerator.cs, + OperationContractGenerationContext.cs : support extensions i.e. + IServiceContractGenerationExtension and IOperation...(ditto) . + +2009-08-10 Atsushi Enomoto <atsushi@ximian.com> + * ServiceContractGenerator.cs : first step to add moonlight-based client proxy generator (it is not supported in 3.5. needs to be enabled by some hook, such as reflection-based hack). diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Description/OperationContractGenerationContext.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Description/OperationContractGenerationContext.cs index 841cf56d9aa..274a2be62be 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Description/OperationContractGenerationContext.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Description/OperationContractGenerationContext.cs @@ -44,7 +44,7 @@ namespace System.ServiceModel.Description CodeTypeDeclaration declaringType, CodeMemberMethod method) : this (serviceContractGenerator, contract, operation, - declaringType, false, method, null) + declaringType, method, null, null) { } @@ -53,38 +53,24 @@ namespace System.ServiceModel.Description ServiceContractGenerationContext contract, OperationDescription operation, CodeTypeDeclaration declaringType, + CodeMemberMethod method, CodeMemberMethod beginMethod, CodeMemberMethod endMethod) - : this (serviceContractGenerator, contract, operation, - declaringType, true, beginMethod, endMethod) - { - } - - private OperationContractGenerationContext ( - ServiceContractGenerator serviceContractGenerator, - ServiceContractGenerationContext contract, - OperationDescription operation, - CodeTypeDeclaration declaringType, - bool isAsync, - CodeMemberMethod method, // sync - CodeMemberMethod endMethod) // async { generator = serviceContractGenerator; this.contract = contract; this.operation = operation; declaring_type = declaringType; this.method = method; + this.begin_method = beginMethod; this.end_method = endMethod; - is_async = isAsync; } - bool is_async; ServiceContractGenerator generator; ServiceContractGenerationContext contract; OperationDescription operation; CodeTypeDeclaration declaring_type; - CodeMemberMethod method; - CodeMemberMethod end_method; + CodeMemberMethod method, begin_method, end_method; public ServiceContractGenerator ServiceContractGenerator { get { return generator; } @@ -98,14 +84,17 @@ namespace System.ServiceModel.Description public CodeTypeDeclaration DeclaringType { get { return declaring_type; } } - public CodeMemberMethod Method { + public CodeMemberMethod SyncMethod { get { return method; } } + public CodeMemberMethod BeginMethod { + get { return begin_method; } + } public CodeMemberMethod EndMethod { get { return end_method; } } public bool IsAsync { - get { return is_async; } + get { return begin_method != null; } } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Description/ServiceContractGenerator.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Description/ServiceContractGenerator.cs index d668dfd1a89..a6db1ae6d7e 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Description/ServiceContractGenerator.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Description/ServiceContractGenerator.cs @@ -55,6 +55,7 @@ namespace System.ServiceModel.Description = new Dictionary<ContractDescription,Type> (); ServiceContractGenerationOptions options; Dictionary<QName, QName> imported_names = null; + ServiceContractGenerationContext contract_context; public ServiceContractGenerator () : this (null, null) @@ -130,15 +131,17 @@ namespace System.ServiceModel.Description { CodeNamespace cns = GetNamespace (contractDescription.Namespace); imported_names = new Dictionary<QName, QName> (); - try { - return ExportInterface (contractDescription, cns); - } finally { - if ((Options & ServiceContractGenerationOptions.ClientClass) != 0) - GenerateProxyClass (contractDescription, cns); - - if ((Options & ServiceContractGenerationOptions.ChannelInterface) != 0) - GenerateChannelInterface (contractDescription, cns); - } + var ret = ExportInterface (contractDescription, cns); + + // FIXME: handle duplex callback + + if ((Options & ServiceContractGenerationOptions.ChannelInterface) != 0) + GenerateChannelInterface (contractDescription, cns); + + if ((Options & ServiceContractGenerationOptions.ClientClass) != 0) + GenerateProxyClass (contractDescription, cns); + + return ret; } CodeNamespace GetNamespace (string ns) @@ -178,6 +181,8 @@ namespace System.ServiceModel.Description type.BaseTypes.Add (clientBase); type.BaseTypes.Add (new CodeTypeReference (cd.Name)); + contract_context = new ServiceContractGenerationContext (this, cd, type); + // .ctor() CodeConstructor ctor = new CodeConstructor (); ctor.Attributes = MemberAttributes.Public; @@ -245,6 +250,13 @@ namespace System.ServiceModel.Description // Add channelbase GenerateProxyChannelClass (cd, type, clientBase); #endif + + // add extensions + foreach (var cb in cd.Behaviors) { + var gex = cb as IServiceContractGenerationExtension; + if (gex != null) + gex.GenerateContract (contract_context); + } } void GenerateProxyChannelClass (ContractDescription cd, CodeTypeDeclaration parentClass, CodeTypeReference clientBaseType) @@ -444,6 +456,8 @@ namespace System.ServiceModel.Description // EndXxx() implementation cm = new CodeMemberMethod (); + cm.Attributes = MemberAttributes.Public + | MemberAttributes.Final; type.Members.Add (cm); cm.Name = "End" + od.Name; @@ -475,13 +489,17 @@ namespace System.ServiceModel.Description void AddImplementationChannelMethods (CodeTypeDeclaration type, ContractDescription cd) { + CodeMemberMethod syncMethod = null, beginMethod = null, endMethod = null; foreach (OperationDescription od in cd.Operations) { CodeMemberMethod cm = new CodeMemberMethod (); type.Members.Add (cm); - if (GenerateAsync) + if (GenerateAsync) { cm.Name = "Begin" + od.Name; - else + beginMethod = cm; + } else { cm.Name = od.Name; + syncMethod = cm; + } cm.Attributes = MemberAttributes.Public | MemberAttributes.Final; CodeTypeReference returnTypeFromMessageContract = null; @@ -535,14 +553,19 @@ namespace System.ServiceModel.Description cm.Statements.Add (new CodeMethodReturnStatement (call)); // For async mode, add EndXxx() too. - if (!GenerateAsync) - return; + if (!GenerateAsync) { + ProcessOperationContextExtensions (od, type, syncMethod, null, null); + continue; + } // EndXxx() implementation cm = new CodeMemberMethod (); + cm.Attributes = MemberAttributes.Public + | MemberAttributes.Final; type.Members.Add (cm); cm.Name = "End" + od.Name; + endMethod = cm; var res = new CodeParameterDeclarationExpression (new CodeTypeReference (typeof (IAsyncResult)), "result"); cm.Parameters.Add (res); @@ -572,6 +595,21 @@ namespace System.ServiceModel.Description cm.Statements.Add (new CodeExpressionStatement (call)); else cm.Statements.Add (new CodeMethodReturnStatement (call)); + + ProcessOperationContextExtensions (od, type, syncMethod, beginMethod, endMethod); + } + } + + void ProcessOperationContextExtensions (OperationDescription od, CodeTypeDeclaration type, CodeMemberMethod sync, CodeMemberMethod begin, CodeMemberMethod end) + { + OperationContractGenerationContext octx = null; + foreach (var ob in od.Behaviors) { + var gex = ob as IOperationContractGenerationExtension; + if (gex == null) + continue; + if (octx == null) + octx = new OperationContractGenerationContext (this, contract_context, od, type, sync, begin, end); + gex.GenerateOperation (octx); } } @@ -616,7 +654,7 @@ namespace System.ServiceModel.Description { throw new NotImplementedException (); } - + private void ExportDataContract (XmlTypeMapping mapping) { if (mapping == null) |