Back to Index | Troubleshooting | Getting Started | Glossary
- No. You can implement
IUntargetedMessage<T>,ITargetedMessage<T>, orIBroadcastMessage<T>directly (recommended for structs). Attributes are optional and help tooling/source-gen.
- No. The source generator and analyzers run for code in Unity's default
Assembly-CSharpand in your own assembly definitions alike, so you do not need to add an.asmdefjust to get generation. Mark the message typepartialand apply a[DxUntargetedMessage]/[DxTargetedMessage]/[DxBroadcastMessage]attribute (or implement the matchingI*Messageinterface). If generated members are missing, see Troubleshooting.
- Untargeted - global notifications (any listener).
- Targeted - commands/events for a specific recipient.
- Broadcast - facts emitted from a source that others may observe.
- Steady-state dispatch is allocation-free: emitting a struct message and invoking a registered handler allocates nothing after the first warm-up emit of that message type (a one-time JIT cost in the editor that IL2CPP precompiles away). The by-ref (
FastHandler) handler overloads also avoid copying the struct on each call; the by-valueAction<T>overloads add one struct copy per dispatch but still do not allocate. Heap allocations come from constructing a class message instance; boxing happens only if you upcast a struct message to a non-generic interface yourself. Registration itself allocates a small, bounded amount per handler (delegates and dictionary entries), so register handlers inAwake/setup rather than every frame. See Performance for measured numbers and Troubleshooting if you observe unexpected allocations.
- Use the
priorityparameter at registration; lower runs earlier. Interceptors run before handlers; post-processors run after.
- Yes. Use
RegisterTargetedWithoutTargeting<T>orRegisterBroadcastWithoutSource<T>(and their post-processor counterparts).
- Enable logs and diagnostics: Diagnostics.
The most common cause is forgetting to call base.Awake() (or base.OnEnable(), base.OnDisable(), base.OnDestroy(), base.RegisterMessageHandlers()) when you override one of those methods. The framework's setup runs in those base calls; without them, your registration token is never created or your handlers never enable. The Roslyn analyzer flags this as DXMSG006. See Inheritance and base calls for the full list of guarded methods.
- The newly registered listener will not run for the current message emission. It will only become active starting with the next message emission.
- This is called "snapshot semantics" -- when a message is emitted, DxMessaging takes a snapshot of all current listeners and uses that frozen list for the entire emission.
- This applies to all listener types (handlers, interceptors, post-processors) and all message categories (Untargeted, Targeted, Broadcast).
- This behavior prevents infinite loops and ensures predictable execution order. See Interceptors & Ordering for details and examples.
- A global bus is provided (
MessageHandler.MessageBus). You can also create and pass your ownMessageBusinstance to isolate subsystems and tests.
- Yes. Installers ship for VContainer, Zenject, and Reflex; see Integrations. They wire the message bus into the container so your message-aware types resolve and register through it instead of reaching for the global bus.
- Construct a dedicated
MessageBusper test and pass it to the participants instead of using the global bus, so registrations cannot leak between tests. Emit a message, then assert your handler observed it. Isolating the bus also lets tests run in parallel without cross-talk.
- Yes. You can integrate with legacy patterns via
ReflexiveMessage. Prefer DxMessaging for new code.
- Each scene introduces new
InstanceIds and sometimes new message types, which add empty slots on the bus when their handlers tear down. Idle eviction will reclaim them eventually; for deterministic cleanup callMessageHandler.TrimAll(force: true)on scene unload (orbus.Trim(force: true)for a non-global bus). See the Memory Reclamation guide for the full pattern.
- New to DxMessaging?
- to Visual Guide -- Beginner-friendly introduction
- to Getting Started -- Complete guide
- to Glossary -- All terms explained
- Common Issues
- to Troubleshooting -- Solutions to common problems
- to Common Patterns -- See how to use it correctly
- Reference
- to Quick Reference -- API cheat sheet
- to Message Types -- Which type to use when