bcquality/microsoft/knowledge/events/choose-static-vs-manual-subscribers-deliberately.md
Jesper Schulz-Wedde b6da405376 Improve partner onboarding and documentation navigation
Lead with a complete plugin quick start and add task-oriented usage, troubleshooting, customization, and contribution guides. Preserve the broader plugin framing, correct conflicting contract guidance, support Agents folder reviews, and align repository validation. Convert existing sample references to clickable links without changing knowledge rules.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-09-09 17:25:29 +02:00

2.5 KiB

bc-version domain keywords technologies countries application-area
all
events
event-subscriber
static-subscriber
manual-subscriber
bindsubscription
unbindsubscription
eventsubscriberinstance
scoped-binding
al
w1
all

Choose static vs manual subscribers deliberately and bind manual ones with BindSubscription

Description

An [EventSubscriber] codeunit is static by default (EventSubscriberInstance = StaticAutomatic): it is always bound, so it fires for every raise of the event in every session. That is correct for always-on behaviour such as auditing, but wrong for behaviour that must be scoped — test isolation, a one-off migration, or a conditional override — because a static subscriber cannot be switched off. For scoped behaviour, set EventSubscriberInstance = Manual and activate the codeunit only while needed with BindSubscription, releasing it with UnbindSubscription. LLMs are largely unaware the manual model exists and default everything to static, producing always-on side effects that leak across unrelated operations and tests.

Best Practice

Use a static subscriber for behaviour that genuinely applies all the time. For anything scoped, mark the codeunit EventSubscriberInstance = Manual, call BindSubscription(SubscriberInstance) at the start of the scope and UnbindSubscription(SubscriberInstance) at the end. A manual subscriber held only in a local variable unbinds automatically when that variable leaves scope, which suits test setup/teardown; a binding you intend to outlive a single call must be unbound explicitly. Keep subscriber methods local per CodeCop AA0207.

See sample: choose-static-vs-manual-subscribers-deliberately.good.al.

Anti Pattern

Two shapes. First, a static subscriber used for behaviour that should be scoped — an always-on side effect (sending mail, writing extra records) that now fires for every event in every session and test with no way to disable it. Second, a manual subscriber that is bound with BindSubscription and never unbound: when the instance is held beyond the intended scope (for example on a SingleInstance codeunit), the binding leaks for the whole session and later unrelated operations keep hitting it. Detection: scoped side effects on a static subscriber, or a BindSubscription call with no matching UnbindSubscription and no scope that releases the instance.

See sample: choose-static-vs-manual-subscribers-deliberately.bad.al.