Module execution lifecycle
A module combines execution policy, module-owned virtual hooks, opt-in attribute handlers, and global event receivers.
Execution phases
For a module that runs successfully, the phases are:
- Dependencies become ready.
- Global
IModuleEventReceiver.OnModuleReadyAsyncreceivers run concurrently. - Attribute
IModuleReadyHandlerhandlers run sequentially by priority. - Global
IModuleEventReceiver.OnModuleStartAsyncreceivers run concurrently. - Attribute
IModuleStartHandlerhandlers run sequentially by priority. - The module skip condition is evaluated.
Module<T>.OnBeforeExecuteAsyncruns once.Module<T>.ExecuteAsyncruns through timeout and retry policies.Module<T>.OnAfterExecuteAsyncruns once.- Global
IModuleEventReceiver.OnModuleEndAsyncreceivers run concurrently. - Attribute
IModuleEndHandlerhandlers run sequentially by priority. - The module result is published and dependants become eligible.
OnBeforeExecuteAsync and OnAfterExecuteAsync wrap the complete retry policy, not each
individual attempt.
Skipped modules
The skip condition is evaluated before the module-owned before hook. If it returns a skip decision:
Module<T>.OnSkippedAsync- Attribute
IModuleSkippedHandler - Global
IModuleEventReceiver.OnModuleSkippedAsync
OnBeforeExecuteAsync, ExecuteAsync, and OnAfterExecuteAsync do not run.
Failed modules
When module execution throws:
Module<T>.OnFailedAsyncModule<T>.OnAfterExecuteAsync, with a failedModuleResult<T>- Attribute
IModuleFailureHandler - Global
IModuleEventReceiver.OnModuleFailureAsync
Retry attempts complete before this failure sequence. If the configured failure condition ignores the failure, the resulting module status reflects that policy.
Hook failures
- An exception from
OnBeforeExecuteAsyncprevents module execution.OnFailedAsyncand the failure event receivers are notified, butOnAfterExecuteAsyncdoes not run. - Exceptions from
OnFailedAsync,OnSkippedAsync, andOnAfterExecuteAsyncare logged and do not replace the module outcome. - Attribute handlers propagate by default. Set their
ContinueOnErrorproperty to continue after a handler failure. - Exceptions from global event receivers propagate from the lifecycle event.
Choosing an extension point
Use module virtual hooks when behavior is part of one module. Use attribute handlers when
behavior should be explicitly attached to selected module types. Use IModuleEventReceiver
when one service must observe every module in the pipeline.
See Hooks for implementation examples.