Skip to content

Attribute-Driven Events: Replace with direct module-level hooks #1868

@thomhurst

Description

@thomhurst

Problem

Module events are driven through reflection + Mediator pattern (IRegistrationEventExecutor, IModuleStartEventReceiver, etc.) causing:

  • Indirection Complexity: Hidden control flow via attributes and reflection
  • Performance Overhead: Reflection to discover attributes, mediator dispatching
  • Hard to Debug: Control flow not obvious, scattered across attributes and receivers
  • Implicit Behavior: Attributes affect execution but aren't visible in module definition
  • Order Uncertainty: No clear ordering for multiple event handlers

Current Design

// Attribute defines event but effect is hidden
[DependsOn<SomeModule>]
[ModuleInitializer]
public class MyModule : Module<string> { ... }

// Event handling scattered in separate receiver classes
public class MyEventReceiver : IModuleStartEventReceiver
{
    public async Task OnModuleStartAsync(...) => ...
}

Proposed Solution

Direct module-level override methods, no attributes:

public class MyModule : Module<string>
{
    protected override async Task OnBeforeExecuteAsync(IPipelineContext context)
    {
        // Clear, visible lifecycle hook
    }
    
    protected override async Task OnAfterExecuteAsync(
        IPipelineContext context,
        ModuleResult<string?> result)
    {
        // Clear, visible lifecycle hook
    }
}

Benefits

  • Explicit control flow in module definition
  • No hidden attribute-driven behavior
  • Easier to understand and debug
  • Better performance
  • Clear lifecycle visibility
  • No need for separate receiver classes

Impact

  • Removes hidden reflection overhead
  • Makes module behavior explicit
  • Simplifies event handling mental model

Priority: HIGH - Breaking change, improves transparency and debuggability

Metadata

Metadata

Assignees

No one assigned

    Labels

    .NETPull requests that update .net codeenhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions