Best Practices & Anti‑patterns
This section collects practical recommendations for using Postboy’s lifecycle management features effectively. Following these guidelines helps keep your message‑driven code clean, predictable, and free of memory leaks.
Best Practices
1. Always call the cleanup function
Every scoping mechanism has a dedicated cleanup trigger. Make sure it is called when the owning component, service, or module is destroyed.
Mechanism | Cleanup trigger |
|---|---|
Registrator |
|
Namespace |
|
Depending service |
|
2. Use unique namespace names
A namespace string must be unique across your application. If multiple instances of the same class exist, append an identifier.
3. Keep scoping close to the owner
Register messages and subscriptions inside the class that owns their lifecycle. Avoid spreading namespace creation or registrator setup across unrelated files.
4. Choose the simplest mechanism for the job
One or two messages in a single class? → Namespace.
Entire feature with many messages? → Registrator.
Service logic that depends on a parent registrator? →
IPostboyDependingService.
Avoid creating a full registrator for a single event.
5. Test handlers independently
Both registrators and namespace callbacks should contain minimal logic. Delegate business rules to plain functions or handler classes that can be tested without the bus.
6. Keep message contracts small
Each message should carry only the data needed to describe what happened or what is requested. Do not use messages as generic data containers.
Anti‑patterns
1. Forgetting to clean up
If a namespace is not eliminated, its subscriptions live forever. Always pair AddNamespace with a corresponding EliminateNamespace in a destructor.
2. Using one global namespace for everything
A single namespace defeats the purpose of scoping — you lose the ability to clean up only a subset of subscriptions.
3. Mixing registration strategies in one place
Choose one strategy per message set and stick to it.
4. Creating a registrator for trivial cases
Registrators add structure; for a single event, a namespace is simpler and just as safe.
5. Relying on manual unsubscription
Postboy’s scoping mechanisms exist to eliminate manual subscription arrays. Use them instead of raw unsubscribe() calls.
6. Subscribing in the constructor without order guarantees
If AuthService is instantiated before the registrator that owns UserLoginEvent, this code throws. Use IPostboyDependingService to delay subscription until the bus is ready.
Summary
Always call the cleanup trigger for every scope you create.
Use unique, descriptive names for namespaces.
Match the scoping strategy to the size and lifetime of the feature.
Keep message handlers and contracts focused.
Let Postboy manage subscription lifecycles — do not revert to manual unsubscribe arrays.