override protected void PostHandleInterface(IDLInterface idlIntf, CodeCompileUnit unit, CodeNamespace ns, CodeTypeDeclaration typeInterface) { if (idlIntf.Signals == null || idlIntf.Signals.Count == 0) // If no signals { typeInterface.CustomAttributes.Add(CodeBuilderCommon.attribServiceContract); } // Ends if no signals // Add DbusServiceRelativeAddress constant to Constants class. // * public partial class Constants { CodeTypeDeclaration typedeclConstants = new CodeTypeDeclaration(CodeBuilderCommon.nameConstantsClass); typedeclConstants.Attributes = MemberAttributes.Public | MemberAttributes.Static; typedeclConstants.IsPartial = true; // * public const string DbusServiceRelativeAddress = "<contract_name>"; // * } CodeMemberField fieldRelativeAddress = new CodeMemberField(typeof(string), CodeBuilderCommon.nameRelativeAddress); fieldRelativeAddress.Attributes = MemberAttributes.Const | MemberAttributes.Public; fieldRelativeAddress.InitExpression = new CodePrimitiveExpression(idlIntf.Name.Replace('.', '/')); typedeclConstants.Members.Add(fieldRelativeAddress); ns.Types.Add(typedeclConstants); CodeTypeReference typerefInterface = new CodeTypeReference(CodeBuilderCommon.GetScopedName(ns.Name, typeInterface.Name)); CodeTypeReference typerefInterfaceProxy = new CodeTypeReference(typeof(Udbus.WCF.Client.Proxy <>)); typerefInterfaceProxy.TypeArguments.Add(typerefInterface); CodeTypeReference typerefProxy; // Worked out in following code... if (this.typedeclProxy == null) // If no proxy type defined yet { // Just knock up a nice vanilla one for consistency's sake. string nsWCFName, intfWCF; nsWCFName = CodeBuilderCommon.GetNamespace(idlIntf.Name, this.visitorType); intfWCF = CodeBuilderCommon.GetName(idlIntf.Name, null); CodeTypeDeclaration typedeclProxy = new CodeTypeDeclaration(CodeBuilderCommon.GetSignalProxyName(intfWCF)); typedeclProxy.BaseTypes.Add(typerefInterfaceProxy); AddProxyConstructors(typedeclProxy); CodeNamespace nsClient = this.GetClientNamespace(unit, idlIntf.Name); nsClient.Types.Add(typedeclProxy); typerefProxy = new CodeTypeReference(CodeBuilderCommon.GetScopedName(nsClient.Name, typedeclProxy.Name)); } // Ends if no proxy type defined yet else // Else added proxy type { // Grab holder of scoped type reference. string nsWCFClient = CodeBuilderCommon.GetNamespace(idlIntf.Name, new WCFClientVisitor()); typerefProxy = new CodeTypeReference(CodeBuilderCommon.GetScopedName(nsWCFClient, this.typedeclProxy.Name)); } // Ends else added proxy type // Reset helper types for next time. this.typedeclCallbackInterface = null; this.typedeclCallbackClient = null; this.typedeclProxy = null; // Add Proxy creation function to ProxyBuilder class via extension method. CodeTypeReference typerefEndpointComponents = new CodeTypeReference(typeof(Udbus.WCF.Client.DbusEndpointUriComponents)); CodeTypeReferenceExpression typerefexprEndpointComponents = new CodeTypeReferenceExpression(typerefEndpointComponents); CodeTypeReference typerefProxyManager = new CodeTypeReference(typeof(Udbus.WCF.Client.ProxyManager)); CodeTypeReferenceExpression typerefexprProxyManager = new CodeTypeReferenceExpression(typerefProxyManager); CodeTypeReference typerefProxyBuilder = new CodeTypeReference(typeof(Udbus.WCF.Client.ProxyBuilder)); CodeTypeReference typerefProxyBuilderExtension = new CodeTypeReference("this " + typerefProxyBuilder.BaseType); // No CodeDom support for extension methods. Awesome. CodeTypeReferenceExpression typerefexprProxyBuilder = new CodeTypeReferenceExpression(typerefProxyBuilder); CodeTypeReferenceExpression typerefexprConstants = new CodeTypeReferenceExpression(CodeBuilderCommon.GetScopedName(ns.Name, typedeclConstants.Name)); CodeParameterDeclarationExpression paramdeclInterfaceProxy = new CodeParameterDeclarationExpression(typerefInterfaceProxy, proxy); CodeParameterDeclarationExpression paramdeclProxyManagerExtension = new CodeParameterDeclarationExpression(typerefProxyBuilderExtension, proxyBuilder); CodeParameterDeclarationExpression paramdeclEndpointUri = new CodeParameterDeclarationExpression(typerefEndpointComponents, dbusEndpointUri); CodeArgumentReferenceExpression argrefProxy = new CodeArgumentReferenceExpression(proxy); CodeArgumentReferenceExpression argrefEndpointUri = new CodeArgumentReferenceExpression(paramdeclEndpointUri.Name); CodeExpression exprRelativeAddress = new CodeFieldReferenceExpression(typerefexprConstants, fieldRelativeAddress.Name); CodeArgumentReferenceExpression argrefProxyBuilder = new CodeArgumentReferenceExpression(proxyBuilder); CodePropertyReferenceExpression proprefBindingFactory = new CodePropertyReferenceExpression(argrefProxyBuilder, BindingFactory); // * static public partial class ProxyBuilderExtensions // * { CodeTypeDeclaration typedeclProxyBuilderExtensions = new CodeTypeDeclaration(CodeBuilderCommon.nameProxyBuilderExtensionsClass); typedeclProxyBuilderExtensions.Attributes = MemberAttributes.Public | MemberAttributes.Static; typedeclProxyBuilderExtensions.IsPartial = true; // http://stackoverflow.com/questions/6308310/creating-extension-method-using-codedom typedeclProxyBuilderExtensions.Attributes = MemberAttributes.Public; typedeclProxyBuilderExtensions.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, Environment.NewLine + "\tstatic")); typedeclProxyBuilderExtensions.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, string.Empty)); // * static public void Create(this Udbus.WCF.Client.ProxyBuilder proxyBuilder, out Udbus.WCF.Client.Proxy< <wcf_contract> > proxy // * , Udbus.WCF.Client.DbusEndpointUriComponents dbusEndpointUri) // * { // * proxy = Udbus.WCF.Client.ProxyManager.Create< <wcf_contract> >( // * dbusEndpointUri.CreateUri(<wcf_namespace>.wcf.Contracts.Constants.DbusServiceRelativeAddress) // * , proxyBuilder.BindingFactory // * ); // * } CodeMemberMethod methodCreateInterfaceProxyWithEndpoint = new CodeMemberMethod(); methodCreateInterfaceProxyWithEndpoint.Name = "Create"; methodCreateInterfaceProxyWithEndpoint.Attributes = MemberAttributes.Static | MemberAttributes.Public; paramdeclInterfaceProxy.Direction = FieldDirection.Out; methodCreateInterfaceProxyWithEndpoint.Parameters.Add(paramdeclProxyManagerExtension); methodCreateInterfaceProxyWithEndpoint.Parameters.Add(paramdeclInterfaceProxy); methodCreateInterfaceProxyWithEndpoint.Parameters.Add(paramdeclEndpointUri); // * dbusEndpointUri.CreateUri(<ns>.wcf.Contracts.Constants.DbusServiceRelativeAddress) CodeMethodInvokeExpression invokeCreateUri = new CodeMethodInvokeExpression(argrefEndpointUri, CreateUri, exprRelativeAddress); CodeMethodInvokeExpression invokeProxyManagerCreate = new CodeMethodInvokeExpression(typerefexprProxyManager, "Create", invokeCreateUri, proprefBindingFactory); invokeProxyManagerCreate.Method.TypeArguments.Add(typerefInterface); methodCreateInterfaceProxyWithEndpoint.Statements.Add( new CodeAssignStatement( argrefProxy , invokeProxyManagerCreate ) ); typedeclProxyBuilderExtensions.Members.Add(methodCreateInterfaceProxyWithEndpoint); // * static public void Create(this Udbus.WCF.Client.ProxyBuilder proxyBuilder, out Udbus.WCF.Client.Proxy< <wcf_contract> > proxy) // * { // * proxyBuilder.Create(out proxy, Udbus.WCF.Client.DbusEndpointUriComponents.Create(proxyBuilder.AbsoluteUribuilder)); // * } CodeMemberMethod methodCreateInterfaceProxy = new CodeMemberMethod(); methodCreateInterfaceProxy.Name = "Create"; methodCreateInterfaceProxy.Attributes = MemberAttributes.Static | MemberAttributes.Public; methodCreateInterfaceProxy.Parameters.Add(paramdeclProxyManagerExtension); methodCreateInterfaceProxy.Parameters.Add(paramdeclInterfaceProxy); CodeMethodInvokeExpression invokeProxyManagerExtensionCreate = new CodeMethodInvokeExpression( argrefProxyBuilder , "Create" , new CodeDirectionExpression(FieldDirection.Out, argrefProxy) , new CodeMethodInvokeExpression( typerefexprEndpointComponents , "Create" , new CodePropertyReferenceExpression(argrefProxyBuilder, AbsoluteUribuilder) ) ); methodCreateInterfaceProxy.Statements.Add(invokeProxyManagerExtensionCreate); typedeclProxyBuilderExtensions.Members.Add(methodCreateInterfaceProxy); CodeParameterDeclarationExpression paramdeclProxy = new CodeParameterDeclarationExpression(typerefProxy, proxy); paramdeclProxy.Direction = FieldDirection.Out; // * public static void Create(this Udbus.WCF.Client.ProxyBuilder proxyBuilder, out <namespace>.Contracts.Clients.<interface>Proxy proxy, Udbus.WCF.Client.DbusEndpointUriComponents dbusEndpointUri) // * { // * proxy = new <wcf_namespace>.Contracts.Clients.<interface>Proxy(proxyBuilder.BindingFactory, dbusEndpointUri.CreateUri(<namespace>.wcf.Contracts.Constants.DbusServiceRelativeAddress)); // * } CodeMemberMethod methodCreateProxyWithEndpoint = new CodeMemberMethod(); methodCreateProxyWithEndpoint.Name = "Create"; methodCreateProxyWithEndpoint.Attributes = MemberAttributes.Static | MemberAttributes.Public; methodCreateProxyWithEndpoint.Parameters.Add(paramdeclProxyManagerExtension); methodCreateProxyWithEndpoint.Parameters.Add(paramdeclProxy); methodCreateProxyWithEndpoint.Parameters.Add(paramdeclEndpointUri); methodCreateProxyWithEndpoint.Statements.Add(new CodeAssignStatement( argrefProxy , new CodeObjectCreateExpression(typerefProxy , proprefBindingFactory , invokeCreateUri ) )); typedeclProxyBuilderExtensions.Members.Add(methodCreateProxyWithEndpoint); // * public static void Create(this Udbus.WCF.Client.ProxyBuilder proxyBuilder, out <namespace>.Contracts.Clients.<interface>Proxy proxy) // * { // * proxyBuilder.Create(out proxy, Udbus.WCF.Client.DbusEndpointUriComponents.Create(proxyBuilder.AbsoluteUribuilder)); // * } CodeMemberMethod methodCreateProxy = new CodeMemberMethod(); methodCreateProxy.Name = "Create"; methodCreateProxy.Attributes = MemberAttributes.Static | MemberAttributes.Public; methodCreateProxy.Parameters.Add(paramdeclProxyManagerExtension); methodCreateProxy.Parameters.Add(paramdeclProxy); methodCreateProxy.Statements.Add(invokeProxyManagerExtensionCreate); typedeclProxyBuilderExtensions.Members.Add(methodCreateProxy); CodeNamespace nsClientExtensions = new CodeNamespace(CodeBuilderCommon.nsClientExtensions); nsClientExtensions.Types.Add(typedeclProxyBuilderExtensions); unit.Namespaces.Add(nsClientExtensions); // * } }
override protected void PostHandleSignal(IDLInterface idlIntf, IDLSignal idlSignal, CodeCompileUnit unit, CodeNamespace ns, CodeTypeDeclaration typeInterface) { string nsName, intf; int lastDot = idlIntf.Name.LastIndexOf('.'); intf = idlIntf.Name.Substring(lastDot + 1); nsName = CodeBuilderCommon.GetNamespace(idlIntf.Name, new InterfaceVisitor()); CodeFieldReferenceExpression fieldrefCallback = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), CodeBuilderCommon.callback); CodeFieldReferenceExpression fieldrefTarget = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), CodeBuilderCommon.targetName); CodeNamespace nsClient = this.GetClientNamespace(unit, idlIntf.Name); CodeNamespace nsClientTypes = nsClient; if (this.typedeclCallbackInterface == null) // If no callback interface yet { CodeTypeReference typerefInterface = new CodeTypeReference(typeInterface.Name); // Declare callback interface and hold onto it in field. // * public interface I<interface>Callback // * { string nsWCFName, intfWCF; nsWCFName = CodeBuilderCommon.GetNamespace(idlIntf.Name, this.visitorType); intfWCF = CodeBuilderCommon.GetName(idlIntf.Name, null); string callbackInterfaceName = CodeBuilderCommon.GetSignalCallbackInterfaceName(intfWCF); typedeclCallbackInterface = new CodeTypeDeclaration(callbackInterfaceName); typedeclCallbackInterface.Attributes = MemberAttributes.Public; typedeclCallbackInterface.IsInterface = true; ns.Types.Add(typedeclCallbackInterface); // * class <interface>CallbackClient : I<interface>Callback string wcfCallbackClientName = CodeBuilderCommon.GetSignalCompilableName(intfWCF) + "CallbackClient"; CodeTypeReference typerefCallbackInterface = new CodeTypeReference(typedeclCallbackInterface.Name); CodeAttributeDeclaration attribdeclServiceContract = new CodeAttributeDeclaration(CodeBuilderCommon.typerefServiceContract, new CodeAttributeArgument("CallbackContract", new CodeTypeOfExpression(typerefCallbackInterface)) ); typeInterface.CustomAttributes.Add(attribdeclServiceContract); //string scopedCallbackInterfaceName = CodeBuilderCommon.GetScopedName(nsWCFName, proxyInterfaceName); //typedeclCallbackClient = new CodeTypeDeclaration(CodeBuilderCommon.GetSignalCallbackName(intf)); typedeclCallbackClient = new CodeTypeDeclaration(wcfCallbackClientName); CodeTypeReference typerefWCFCallbackInterface = new CodeTypeReference(typedeclCallbackInterface.Name); typedeclCallbackClient.BaseTypes.Add(typerefWCFCallbackInterface); nsClientTypes.Types.Add(typedeclCallbackClient); // * public class <interface>Proxy : Udbus.WCF.Client.CallbackProxy< <wcf_contracts.interface>, <interface>CallbackClient > this.typedeclProxy = new CodeTypeDeclaration(CodeBuilderCommon.GetSignalProxyName(intfWCF)); CodeTypeReference typerefCallbackProxy = new CodeTypeReference(typeof(Udbus.WCF.Client.CallbackProxy <,>)); CodeTypeReference typerefCallbackClient = new CodeTypeReference(typedeclCallbackClient.Name); typerefCallbackProxy.TypeArguments.Add(typerefInterface); typerefCallbackProxy.TypeArguments.Add(typerefCallbackClient); this.typedeclProxy.BaseTypes.Add(typerefCallbackProxy); AddProxyConstructors(this.typedeclProxy); nsClientTypes.Types.Add(this.typedeclProxy); } // Ends if no callback interface yet // Add signal property to Proxy. CodeMemberProperty propProxySignal = CodeBuilderCommon.CreateSignalEventProperty(idlSignal); propProxySignal.Attributes = MemberAttributes.Public | MemberAttributes.Final; CodePropertyReferenceExpression proprefProxyInterface = new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "ProxyInterface"); CodePropertyReferenceExpression proprefProxyCallback = new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "Callback"); CodePropertyReferenceExpression proprefProxyCallbackEvent = new CodePropertyReferenceExpression(proprefProxyCallback, propProxySignal.Name); propProxySignal.GetStatements.Add(new CodeMethodReturnStatement(proprefProxyCallbackEvent)); propProxySignal.SetStatements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(proprefProxyCallbackEvent, CodeBinaryOperatorType.IdentityEquality, new CodePrimitiveExpression(null)) , new CodeExpressionStatement(new CodeMethodInvokeExpression(proprefProxyInterface, CodeBuilderCommon.GetSignalRegisterFunction(idlSignal.Name))) )); propProxySignal.SetStatements.Add(new CodeAssignStatement(proprefProxyCallbackEvent, new CodePropertySetValueReferenceExpression())); this.typedeclProxy.Members.Add(propProxySignal); // Add callback method to callback interface. // * [System.ServiceModel.OperationContract(IsOneWay=true)] // * void On<signal>(<interface_ns>.<signal>Args args); CodeMemberMethod methodOnSignal = new CodeMemberMethod(); methodOnSignal.Name = CodeBuilderCommon.GetSignalCallbackMethodName(idlSignal.Name); string signalArgsTypeName = CodeBuilderCommon.GetSignalEventTypeName(idlSignal.Name); string scopedSignalArgsTypeName = CodeBuilderCommon.GetScopedName(nsName, signalArgsTypeName); CodeParameterDeclarationExpression paramdeclSignalArgs = new CodeParameterDeclarationExpression(scopedSignalArgsTypeName, CodeBuilderCommon.SignalArgsName); methodOnSignal.Parameters.Add(paramdeclSignalArgs); methodOnSignal.CustomAttributes.Add(CodeBuilderCommon.attribOperationContractOneWay); typedeclCallbackInterface.Members.Add(methodOnSignal); // Add registration method to wcf interface. // * [System.ServiceModel.OperationContract] // * void RegisterForStorageSpaceLow(); CodeMemberMethod methodRegister = new CodeMemberMethod(); methodRegister.Name = CodeBuilderCommon.GetSignalRegisterFunction(idlSignal.Name); methodRegister.CustomAttributes.Add(CodeBuilderCommon.attribOperationContract); typeInterface.Members.Add(methodRegister); // Add event to callback client implementation. // * private event System.EventHandler< <signal>Args > <signal>Event; CodeMemberEvent eventSignal = CodeBuilderCommon.CreateSignalEvent(idlSignal); typedeclCallbackClient.Members.Add(eventSignal); // * public virtual System.EventHandler< <signal>Args > <signal> // * { // * get { return this.<signal>Event; } // * set { this.<signal>Event = value; } // * } CodeMemberProperty propSignal = CodeBuilderCommon.CreateSignalEventProperty(idlSignal); propSignal.Attributes = MemberAttributes.Public | MemberAttributes.Final; CodeEventReferenceExpression eventrefSignal = new CodeEventReferenceExpression(new CodeThisReferenceExpression(), eventSignal.Name); propSignal.GetStatements.Add(new CodeMethodReturnStatement(eventrefSignal)); propSignal.SetStatements.Add(new CodeAssignStatement(eventrefSignal, new CodePropertySetValueReferenceExpression())); typedeclCallbackClient.Members.Add(propSignal); // * public void On<signal>(<ns>.<signal>Args args) // * { // * if (this.<signal> != null) // * { // * this.<signal>(this, args); // * } //} CodeMemberMethod methodSignal = new CodeMemberMethod(); methodSignal.Name = CodeBuilderCommon.GetSignalCallbackMethodName(idlSignal.Name); methodSignal.Attributes = MemberAttributes.Public; methodSignal.Parameters.Add(paramdeclSignalArgs); CodePropertyReferenceExpression proprefSignal = new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), propSignal.Name); methodSignal.Statements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(eventrefSignal, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)) , new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), eventrefSignal.EventName, new CodeThisReferenceExpression(), new CodeArgumentReferenceExpression(paramdeclSignalArgs.Name))) )); typedeclCallbackClient.Members.Add(methodSignal); }