CodeTypeDeclaration declaringType,
CodeMemberMethod method)
: this (serviceContractGenerator, contract, operation,
- declaringType, false, method, null)
+ declaringType, method, null, null)
{
}
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; }
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; }
}
}
}
= new Dictionary<ContractDescription,Type> ();
ServiceContractGenerationOptions options;
Dictionary<QName, QName> imported_names = null;
+ ServiceContractGenerationContext contract_context;
public ServiceContractGenerator ()
: this (null, null)
{
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)
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;
// 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)
// EndXxx() implementation
cm = new CodeMemberMethod ();
+ cm.Attributes = MemberAttributes.Public
+ | MemberAttributes.Final;
type.Members.Add (cm);
cm.Name = "End" + od.Name;
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;
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);
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);
}
}
{
throw new NotImplementedException ();
}
-
+
private void ExportDataContract (XmlTypeMapping mapping)
{
if (mapping == null)