private static Dictionary <string, string> GenerateEventAsyncMethods(CodeTypeNameScope nameScope, CodeTypeDeclaration parent, CodeTypeDeclaration callbackInterface, List <CodeTypeDeclaration> eventArgsList) { Dictionary <string, string> methodNames = new Dictionary <string, string>(); List <CodeMemberEvent> receivedEvents = new List <CodeMemberEvent>(); foreach (CodeMemberMethod method in callbackInterface.Members) { if (IsSyncOperationContract(method)) { // public partial class UploadFileCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs CodeTypeDeclaration eventArgs = CreateOperationReceivedEventArgsType(nameScope, method); if (eventArgs != null) { eventArgsList.Add(eventArgs); } // public event System.EventHandler<UploadFileCompletedEventArgs> UploadFileCompleted; CodeMemberEvent evt = CreateOperationReceivedEvent(nameScope, method, eventArgs); parent.Members.Add(evt); receivedEvents.Add(evt); CodeMemberMethod member = CreateOperationReceivedMethod(nameScope, method, eventArgs, evt); parent.Members.Add(member); System.Diagnostics.Debug.Assert(!methodNames.ContainsKey(method.Name), $"Key '{method.Name}' already added to dictionary!"); methodNames[method.Name] = member.Name; } } return(methodNames); }
protected override void VisitClientClass(CodeTypeDeclaration type) { base.VisitClientClass(type); using (NameScope nameScope = new CodeTypeNameScope(type)) { type.Members.Add(GenerateTaskBasedAsyncMethod("Open", nameScope)); type.Members.Add(GenerateTaskBasedAsyncMethod("Close", nameScope)); } }
private static CodeTypeDeclaration CreateCallbackImplClass(CodeTypeNameScope nameScope, CodeTypeDeclaration parent, CodeTypeDeclaration callbackInterface, Dictionary <string, string> methodNames) { CodeTypeDeclaration callbackImpl = new CodeTypeDeclaration(); callbackImpl.Name = nameScope.UniqueMemberName(parent.Name + "Callback"); callbackImpl.TypeAttributes &= ~TypeAttributes.VisibilityMask; callbackImpl.TypeAttributes |= TypeAttributes.NestedPrivate; callbackImpl.BaseTypes.Add(new CodeTypeReference(typeof(object))); callbackImpl.BaseTypes.Add(new CodeTypeReference(callbackInterface.Name)); AddMembers(callbackImpl, parent); AddInitialize(callbackImpl, parent); AddMethods(callbackImpl, callbackInterface, methodNames); return(callbackImpl); }
private void CreateEventBasedDuplexClass(CodeTypeDeclaration type, CodeTypeDeclaration callbackInterface) { _eventBasedDuplexClass = new CodeTypeDeclaration(type.Name); _eventBasedDuplexClass.IsPartial = true; type.Name += "Base"; _eventBasedDuplexClass.BaseTypes.Add(type.Name); CodeTypeDeclaration callbackImpl; using (CodeTypeNameScope nameScope = new CodeTypeNameScope(_eventBasedDuplexClass)) { Dictionary <string, string> methodNames = GenerateEventAsyncMethods(nameScope, _eventBasedDuplexClass, callbackInterface, _eventArgsList); callbackImpl = CreateCallbackImplClass(nameScope, _eventBasedDuplexClass, callbackInterface, methodNames); _eventBasedDuplexClass.Members.Add(callbackImpl); } // Create ctor CreateCtorOverload(_eventBasedDuplexClass, callbackImpl); }
private static CodeMemberEvent CreateOperationReceivedEvent(CodeTypeNameScope nameScope, CodeMemberMethod syncMethod, CodeTypeDeclaration operationCompletedEventArgsType) { // public event System.EventHandler<OnEcho2CallbackEventArgs> OnEcho2Callback; CodeMemberEvent operationCompletedEvent = new CodeMemberEvent(); operationCompletedEvent.Name = nameScope.UniqueMemberName(syncMethod.Name + "Received"); operationCompletedEvent.Attributes = MemberAttributes.Public; operationCompletedEvent.Type = new CodeTypeReference(typeof(EventHandler)); if (operationCompletedEventArgsType == null) { operationCompletedEvent.Type.TypeArguments.Add(typeof(AsyncCompletedEventArgs)); } else { operationCompletedEvent.Type.TypeArguments.Add(operationCompletedEventArgsType.Name); } return(operationCompletedEvent); }
private static CodeTypeDeclaration CreateOperationReceivedEventArgsType(CodeTypeNameScope nameScope, CodeMemberMethod syncMethod) { if (syncMethod.Parameters.Count <= 0) { // no need to create new event args type, use AsyncCompletedEventArgs return(null); } CodeTypeDeclaration evtArg = new CodeTypeDeclaration(); evtArg.Name = nameScope.UniqueMemberName(syncMethod.Name + "ReceivedEventArgs"); evtArg.BaseTypes.Add(new CodeTypeReference(typeof(AsyncCompletedEventArgs))); // define object[] results field. CodeMemberField resultsField = new CodeMemberField(typeof(object[]), "results"); evtArg.Members.Add(resultsField); // create constructor, that assigns the results field. CodeConstructor ctor = new CodeConstructor(); ctor.Attributes = MemberAttributes.Public; ctor.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object[]), "results")); ctor.Parameters.Add(new CodeParameterDeclarationExpression(typeof(Exception), "exception")); ctor.BaseConstructorArgs.Add(new CodeVariableReferenceExpression("exception")); ctor.Parameters.Add(new CodeParameterDeclarationExpression(typeof(bool), "cancelled")); ctor.BaseConstructorArgs.Add(new CodeVariableReferenceExpression("cancelled")); ctor.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "userState")); ctor.BaseConstructorArgs.Add(new CodeVariableReferenceExpression("userState")); evtArg.Members.Add(ctor); CodeFieldReferenceExpression resultsFieldReference = new CodeFieldReferenceExpression(); resultsFieldReference.TargetObject = new CodeThisReferenceExpression(); resultsFieldReference.FieldName = "results"; ctor.Statements.Add(new CodeAssignStatement(resultsFieldReference, new CodeVariableReferenceExpression("results"))); using (PropertyFieldNameScope typeNamescope = new PropertyFieldNameScope(typeof(AsyncCompletedEventArgs))) { for (int paramIndex = 0; paramIndex < syncMethod.Parameters.Count; paramIndex++) { CodeParameterDeclarationExpression param = syncMethod.Parameters[paramIndex]; CodeMemberProperty property = new CodeMemberProperty(); property.Attributes = MemberAttributes.Public | MemberAttributes.Final; property.Type = param.Type; property.Name = typeNamescope.UniqueMemberName(param.Name); property.HasSet = false; property.HasGet = true; // base.RaiseExceptionIfNecessary(); property.GetStatements.Add(new CodeMethodInvokeExpression(new CodeBaseReferenceExpression(), "RaiseExceptionIfNecessary")); // return ((string)(this.results[0])); CodeCastExpression castExpr = new CodeCastExpression(param.Type, new CodeArrayIndexerExpression(resultsFieldReference, new CodePrimitiveExpression(paramIndex))); CodeMethodReturnStatement returnStmt = new CodeMethodReturnStatement(castExpr); property.GetStatements.Add(returnStmt); evtArg.Members.Add(property); } } return(evtArg); }
private static CodeMemberMethod CreateOperationReceivedMethod(CodeTypeNameScope nameScope, CodeMemberMethod syncMethod, CodeTypeDeclaration operationReceivedEventArgsType, CodeMemberEvent operationCompletedEvent) { CodeMemberMethod operationCompletedMethod = new CodeMemberMethod(); operationCompletedMethod.Name = nameScope.UniqueMemberName("On" + syncMethod.Name + "Received"); operationCompletedMethod.Attributes = MemberAttributes.Private; operationCompletedMethod.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(object)), "state")); operationCompletedMethod.ReturnType = new CodeTypeReference(typeof(void)); // object[] results = ((object[])(state)); CodeVariableDeclarationStatement results = new CodeVariableDeclarationStatement() { Name = "results", Type = new CodeTypeReference(typeof(object[])), InitExpression = new CodeCastExpression() { TargetType = new CodeTypeReference(typeof(object[])), Expression = new CodeVariableReferenceExpression("state"), } }; // new OnEcho2CallbackEventArgs(results, null, false, null) CodeObjectCreateExpression newEventArgsExpr = null; if (operationReceivedEventArgsType != null) { newEventArgsExpr = new CodeObjectCreateExpression(operationReceivedEventArgsType.Name, new CodeVariableReferenceExpression(results.Name), new CodePrimitiveExpression(null), new CodePrimitiveExpression(false), new CodePrimitiveExpression(null) ); } else { newEventArgsExpr = new CodeObjectCreateExpression(typeof(AsyncCompletedEventArgs), new CodePrimitiveExpression(null), new CodePrimitiveExpression(false), new CodePrimitiveExpression(null) ); } // this.OnEcho2Callback(this, new OnEcho2CallbackEventArgs(results, null, false, null)); CodeEventReferenceExpression completedEvent = new CodeEventReferenceExpression(new CodeThisReferenceExpression(), operationCompletedEvent.Name); CodeDelegateInvokeExpression raiseEventExpr = new CodeDelegateInvokeExpression( completedEvent, new CodeThisReferenceExpression(), newEventArgsExpr); //if ((this.OnEcho2Callback != null)) //{ // object[] results = ((object[])(state)); // this.OnEcho2Callback(this, new OnEcho2CallbackEventArgs(results, null, false, null)); //} CodeConditionStatement ifEventHandlerNotNullBlock = new CodeConditionStatement() { Condition = new CodeBinaryOperatorExpression(completedEvent, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)), TrueStatements = { results, raiseEventExpr, } }; operationCompletedMethod.Statements.Add(ifEventHandlerNotNullBlock); return(operationCompletedMethod); }