Skip to content

[Design] PluginSystemOptions.RegisteredALCs is hidden mutable state — side-channel coupling between PluginLoader and PluginManager #16

@pournasserian

Description

@pournasserian

Summary

PluginSystemOptions contains an internal mutable list of AssemblyLoadContext instances (RegisteredALCs). This list is populated by PluginLoader and consumed by PluginManager. Using a public options/configuration object as a hidden communication channel between two components is an anti-pattern: the options class should carry only configuration values, not mutable runtime state.

Location

Plugins/FluentCMS.Infrastructure.Plugins/PluginSystemOptions.cs — line 51

Problematic Code

internal List<AssemblyLoadContext> RegisteredALCs { get; } = [];

Impact

  • Hidden coupling: PluginLoader and PluginManager are implicitly coupled through the shared options object with no documented contract.
  • Unexpected mutation: Any component that holds a reference to PluginSystemOptions can observe or modify the ALC list, which should be an implementation detail.
  • Testing difficulty: Creating a PluginSystemOptions instance in tests doesn't give the expected clean state without knowing about this hidden list.
  • Violation of SRP: PluginSystemOptions now serves two roles: configuration data-bag and runtime ALC registry.

Recommendation

Remove RegisteredALCs from PluginSystemOptions and change LoadPluginTypes to return a result type that packages both outputs together:

public record PluginLoadResult(
    IReadOnlyList<Type> PluginTypes,
    IReadOnlyList<AssemblyLoadContext> LoadContexts
);

// PluginLoader.LoadPluginTypes() returns PluginLoadResult
// PluginManager receives PluginLoadResult directly

This makes the data-flow explicit and removes the hidden state from the configuration object.

Severity

🔵 Design / Maintainability

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions