diff --git a/powershell/cmdlets/class.ts b/powershell/cmdlets/class.ts
index 7b08dff6287..d27c3254b7c 100644
--- a/powershell/cmdlets/class.ts
+++ b/powershell/cmdlets/class.ts
@@ -1022,6 +1022,10 @@ export class CmdletClass extends Class {
// in azure mode, we signal the AzAccount module with every event that makes it here.
yield `await ${$this.state.project.serviceNamespace.moduleClass.declaration}.Instance.Signal(${id.value}, ${token.value}, ${messageData.value}, (i,t,m) => ((${ClientRuntime.IEventListener})this).Signal(i,t,()=> ${ClientRuntime.EventDataConverter}.ConvertFrom( m() ) as ${ClientRuntime.EventData} ), ${$this.invocationInfo.value}, this.ParameterSetName, ${$this.correlationId.value}, ${$this.processRecordId.value}, null );`;
yield If(`${token.value}.IsCancellationRequested`, Return());
+ } else {
+ // In Non-Azure Modes, emit the Signal method without coorelation and processrecordid
+ yield `await ${$this.state.project.serviceNamespace.moduleClass.declaration}.Instance.Signal(${id.value}, ${token.value}, ${messageData.value}, (i,t,m) => ((${ClientRuntime.IEventListener})this).Signal(i,t,()=> ${ClientRuntime.EventDataConverter}.ConvertFrom( m() ) as ${ClientRuntime.EventData} ), ${$this.invocationInfo.value}, this.ParameterSetName, null );`;
+ yield If(`${token.value}.IsCancellationRequested`, Return());
}
yield `WriteDebug($"{id}: {(messageData().Message ?? ${System.String.Empty})}");`;
// any handling of the signal on our side...
diff --git a/powershell/module/module-class.ts b/powershell/module/module-class.ts
index 1bed829add9..18d20a5f45d 100644
--- a/powershell/module/module-class.ts
+++ b/powershell/module/module-class.ts
@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-import { Access, Alias, Class, ClassType, Constructor, dotnet, Field, LambdaMethod, LambdaProperty, LazyProperty, LiteralExpression, LocalVariable, MemberVariable, Method, Modifier, Namespace, Parameter, ParameterModifier, PartialMethod, Property, Return, Statements, StringExpression, System, TypeDeclaration, Using, valueOf, Variable } from '@azure-tools/codegen-csharp';
+import { Access, Alias, Class, ClassType, Constructor, dotnet, Field, LambdaMethod, LambdaProperty, LazyProperty, LiteralExpression, LocalVariable, MemberVariable, Method, Modifier, Namespace, Parameter, ParameterModifier, PartialMethod, Property, Return, Statements, StringExpression, System, TypeDeclaration, Using, valueOf, Variable, If } from '@azure-tools/codegen-csharp';
import { InvocationInfo, PSCredential, IArgumentCompleter, CompletionResult, CommandAst, CompletionResultType, } from '../internal/powershell-declarations';
import { State } from '../internal/state';
@@ -129,6 +129,21 @@ export class ModuleClass extends Class {
createInitAndPipeline(namespace: Namespace) {
const $this = this;
+ // Custom Event Listener without Azure Spefic concepts. (ProcessId and CorelationId)
+ const customEventListenerFunc = System.Func(
+ dotnet.String,
+ System.Threading.CancellationToken,
+ System.Func(System.EventArgs),
+ this.incomingSignalFunc,
+ InvocationInfo,
+ dotnet.String,
+ System.Exception,
+ /* returns */ System.Threading.Tasks.Task());
+
+ const incomingSignalDelegate = namespace.add(new Alias('SignalDelegate', this.incomingSignalFunc));
+ const eventListenerDelegate = namespace.add(new Alias('EventListenerDelegate', customEventListenerFunc));
+ const EventListener = this.add(new Property('EventListener', eventListenerDelegate, { description: 'A delegate that gets called for each signalled event' }));
+
// non-azure init method
this.initMethod.add(function* () {
yield '// called at module init time...';
@@ -152,6 +167,22 @@ export class ModuleClass extends Class {
});
this.add(new LambdaProperty('Name', dotnet.String, new StringExpression(this.state.project.moduleName), { description: 'The Name of this module ' }));
+
+ // Add Signal extensibility point
+ const pSignal = new Parameter('signal', incomingSignalDelegate, { description: 'The callback for the event dispatcher ' });
+ // Emit signal extensibility points that called EventListenerDelegate, allowing us to handle Signals emitted by the Pipeline in the Auth Module
+ const signalImpl = this.add(new Method('Signal', System.Threading.Tasks.Task(), {
+ parameters: [this.pId, this.pToken, this.pGetEventData, pSignal, this.pInvocationInfo, this.pParameterSetName, this.pException], async: Modifier.Async,
+ description: 'Called to dispatch events to the common module listener',
+ returnsDescription: `A that will be complete when handling of the event is completed.`
+ }));
+
+ signalImpl.push(Using('NoSynchronizationContext', ''));
+ signalImpl.add(function* () {
+ // Emit call to EventListener after explicit null check.
+ // Not using Null-Conditional operator causes Null Reference exception when Func is null, due to awaiting null Task.
+ yield If(`${EventListener.value} != null`, `await ${EventListener.value}.Invoke(${$this.pId.value},${$this.pToken.value},${$this.pGetEventData.value}, ${pSignal.value}, ${$this.pInvocationInfo}, ${$this.pParameterSetName},${$this.pException});`)
+ });
}
createAzureInitAndPipeline(namespace: Namespace) {