com.wallstop-studios.dxmessaging 2.0.0-rc27.3.1 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/format-on-demand.yml +2 -2
- package/.github/workflows/json-format-check.yml +1 -1
- package/.github/workflows/markdown-json.yml +1 -1
- package/.github/workflows/markdownlint.yml +1 -1
- package/.github/workflows/npm-publish.yml +1 -1
- package/.github/workflows/prettier-autofix.yml +2 -2
- package/.github/workflows/yaml-format-lint.yml +1 -1
- package/Docs/Advanced.md +26 -1
- package/Docs/Comparisons.md +1352 -141
- package/Docs/Compatibility.md +27 -0
- package/Docs/DesignAndArchitecture.md +41 -34
- package/Docs/EmitShorthands.md +34 -0
- package/Docs/GettingStarted.md +84 -17
- package/Docs/Helpers.md +1 -1
- package/Docs/Index.md +28 -25
- package/Docs/Install.md +29 -6
- package/Docs/Integrations/Reflex.md +292 -0
- package/Docs/Integrations/Reflex.md.meta +7 -0
- package/Docs/Integrations/VContainer.md +324 -0
- package/Docs/Integrations/VContainer.md.meta +7 -0
- package/Docs/Integrations/Zenject.md +333 -0
- package/Docs/Integrations/Zenject.md.meta +7 -0
- package/{Editor/Analyzers/WallstopStudios.DxMessaging.SourceGenerators.pdb.meta → Docs/Integrations.meta} +2 -1
- package/Docs/InterceptorsAndOrdering.md +371 -17
- package/Docs/ListeningPatterns.md +206 -0
- package/Docs/MessageBusProviders.md +496 -0
- package/Docs/MessageBusProviders.md.meta +7 -0
- package/Docs/MessageTypes.md +27 -0
- package/Docs/MigrationGuide.md +45 -0
- package/Docs/Overview.md +114 -20
- package/Docs/Patterns.md +327 -2
- package/Docs/Performance.md +9 -9
- package/Docs/QuickReference.md +31 -0
- package/Docs/RuntimeConfiguration.md +407 -0
- package/Docs/RuntimeConfiguration.md.meta +7 -0
- package/Docs/UnityIntegration.md +3 -1
- package/Docs/VisualGuide.md +281 -167
- package/Editor/Analyzers/Microsoft.CodeAnalysis.CSharp.dll +0 -0
- package/Editor/Analyzers/Microsoft.CodeAnalysis.CSharp.dll.meta +3 -3
- package/Editor/Analyzers/Microsoft.CodeAnalysis.dll +0 -0
- package/Editor/Analyzers/Microsoft.CodeAnalysis.dll.meta +2 -2
- package/Editor/Analyzers/System.Collections.Immutable.dll +0 -0
- package/Editor/Analyzers/System.Reflection.Metadata.dll +0 -0
- package/Editor/Analyzers/System.Runtime.CompilerServices.Unsafe.dll +0 -0
- package/Editor/CustomEditors/MessagingComponentEditor.cs +15 -6
- package/README.md +388 -67
- package/Runtime/AssemblyInfo.cs +4 -0
- package/Runtime/Core/Extensions/MessageBusExtensions.cs +253 -0
- package/Runtime/Core/Extensions/MessageBusExtensions.cs.meta +12 -0
- package/Runtime/Core/Extensions/MessageExtensions.cs +137 -89
- package/Runtime/Core/MessageBus/GlobalMessageBusProvider.cs +23 -0
- package/Runtime/Core/MessageBus/GlobalMessageBusProvider.cs.meta +11 -0
- package/Runtime/Core/MessageBus/IMessageBusProvider.cs +14 -0
- package/Runtime/Core/MessageBus/IMessageBusProvider.cs.meta +11 -0
- package/Runtime/Core/MessageBus/IMessageRegistrationBuilder.cs +18 -0
- package/Runtime/Core/MessageBus/IMessageRegistrationBuilder.cs.meta +11 -0
- package/Runtime/Core/MessageBus/MessageBusRebindMode.cs +26 -0
- package/Runtime/Core/MessageBus/MessageBusRebindMode.cs.meta +11 -0
- package/Runtime/Core/MessageBus/MessageRegistrationBuilder.cs +383 -0
- package/Runtime/Core/MessageBus/MessageRegistrationBuilder.cs.meta +11 -0
- package/Runtime/Core/MessageHandler.cs +198 -27
- package/Runtime/Core/MessageRegistrationToken.cs +67 -25
- package/Runtime/Unity/CurrentGlobalMessageBusProvider.cs +31 -0
- package/Runtime/Unity/CurrentGlobalMessageBusProvider.cs.meta +12 -0
- package/Runtime/Unity/InitialGlobalMessageBusProvider.cs +38 -0
- package/Runtime/Unity/InitialGlobalMessageBusProvider.cs.meta +12 -0
- package/Runtime/Unity/Integrations/Reflex/AssemblyInfo.cs +11 -0
- package/Runtime/Unity/Integrations/Reflex/AssemblyInfo.cs.meta +3 -0
- package/Runtime/Unity/Integrations/Reflex/ReflexRegistrationInstaller.cs +73 -0
- package/Runtime/Unity/Integrations/Reflex/ReflexRegistrationInstaller.cs.meta +11 -0
- package/Runtime/Unity/Integrations/Reflex/WallstopStudios.DxMessaging.Reflex.asmdef +20 -0
- package/Runtime/Unity/Integrations/Reflex/WallstopStudios.DxMessaging.Reflex.asmdef.meta +7 -0
- package/Runtime/Unity/Integrations/Reflex.meta +8 -0
- package/Runtime/Unity/Integrations/VContainer/AssemblyInfo.cs +11 -0
- package/Runtime/Unity/Integrations/VContainer/AssemblyInfo.cs.meta +3 -0
- package/Runtime/Unity/Integrations/VContainer/VContainerRegistrationExtensions.cs +46 -0
- package/Runtime/Unity/Integrations/VContainer/VContainerRegistrationExtensions.cs.meta +11 -0
- package/Runtime/Unity/Integrations/VContainer/WallstopStudios.DxMessaging.VContainer.asmdef +30 -0
- package/Runtime/Unity/Integrations/VContainer/WallstopStudios.DxMessaging.VContainer.asmdef.meta +7 -0
- package/Runtime/Unity/Integrations/VContainer.meta +8 -0
- package/Runtime/Unity/Integrations/Zenject/AssemblyInfo.cs +11 -0
- package/Runtime/Unity/Integrations/Zenject/AssemblyInfo.cs.meta +3 -0
- package/Runtime/Unity/Integrations/Zenject/WallstopStudios.DxMessaging.Zenject.asmdef +30 -0
- package/Runtime/Unity/Integrations/Zenject/WallstopStudios.DxMessaging.Zenject.asmdef.meta +7 -0
- package/Runtime/Unity/Integrations/Zenject/ZenjectRegistrationInstaller.cs +55 -0
- package/Runtime/Unity/Integrations/Zenject/ZenjectRegistrationInstaller.cs.meta +11 -0
- package/Runtime/Unity/Integrations/Zenject.meta +8 -0
- package/Runtime/Unity/Integrations.meta +8 -0
- package/Runtime/Unity/MessageAwareComponent.cs +102 -0
- package/Runtime/Unity/MessageBusProviderHandle.cs +97 -0
- package/Runtime/Unity/MessageBusProviderHandle.cs.meta +12 -0
- package/Runtime/Unity/MessagingComponent.cs +164 -2
- package/Runtime/Unity/MessagingComponentInstaller.cs +120 -0
- package/Runtime/Unity/MessagingComponentInstaller.cs.meta +12 -0
- package/Runtime/Unity/ScriptableMessageBusProvider.cs +14 -0
- package/Runtime/Unity/ScriptableMessageBusProvider.cs.meta +12 -0
- package/Samples~/DI/Prefabs/MessagingInstallerSample.prefab +98 -0
- package/Samples~/DI/Prefabs/MessagingInstallerSample.prefab.meta +7 -0
- package/Samples~/DI/Prefabs.meta +8 -0
- package/Samples~/DI/Providers/GlobalMessageBusProvider.asset +14 -0
- package/Samples~/DI/Providers/GlobalMessageBusProvider.asset.meta +8 -0
- package/Samples~/DI/Providers/InitialGlobalMessageBusProvider.asset +14 -0
- package/Samples~/DI/Providers/InitialGlobalMessageBusProvider.asset.meta +8 -0
- package/Samples~/DI/Providers.meta +8 -0
- package/Samples~/DI/README.md +51 -0
- package/Samples~/DI/README.md.meta +7 -0
- package/Samples~/DI/Reflex/SampleInstaller.cs +75 -0
- package/Samples~/DI/Reflex/SampleInstaller.cs.meta +11 -0
- package/Samples~/DI/Reflex.meta +8 -0
- package/Samples~/DI/VContainer/SampleLifetimeScope.cs +81 -0
- package/Samples~/DI/VContainer/SampleLifetimeScope.cs.meta +11 -0
- package/Samples~/DI/VContainer.meta +8 -0
- package/Samples~/DI/Zenject/SampleInstaller.cs +67 -0
- package/Samples~/DI/Zenject/SampleInstaller.cs.meta +11 -0
- package/Samples~/DI/Zenject.meta +8 -0
- package/Samples~/DI.meta +8 -0
- package/Samples~/Mini Combat/README.md +86 -28
- package/Samples~/Mini Combat/Walkthrough.md +41 -25
- package/Samples~/UI Buttons + Inspector/DiagnosticsEnabler.cs +12 -2
- package/Samples~/UI Buttons + Inspector/README.md +55 -12
- package/Samples~/UI Buttons + Inspector/README.md.meta +7 -0
- package/Tests/Runtime/Benchmarks/BenchmarkSession.cs +444 -0
- package/Tests/Runtime/Benchmarks/BenchmarkSession.cs.meta +11 -0
- package/Tests/Runtime/Benchmarks/BenchmarkTestBase.cs +94 -0
- package/Tests/Runtime/Benchmarks/BenchmarkTestBase.cs.meta +11 -0
- package/Tests/Runtime/Benchmarks/ComparisonPerformanceTests.cs +395 -0
- package/Tests/Runtime/Benchmarks/ComparisonPerformanceTests.cs.meta +11 -0
- package/Tests/Runtime/Benchmarks/PerformanceTests.cs +77 -429
- package/Tests/Runtime/Benchmarks/ProviderResolutionBenchmarks.cs +142 -0
- package/Tests/Runtime/Benchmarks/ProviderResolutionBenchmarks.cs.meta +12 -0
- package/Tests/Runtime/Benchmarks/WallstopStudios.DxMessaging.Tests.Runtime.Benchmarks.asmdef +50 -0
- package/Tests/Runtime/Benchmarks/WallstopStudios.DxMessaging.Tests.Runtime.Benchmarks.asmdef.meta +7 -0
- package/Tests/Runtime/Core/DefaultBusFallbackTests.cs +333 -0
- package/Tests/Runtime/Core/DefaultBusFallbackTests.cs.meta +11 -0
- package/Tests/Runtime/Core/Extensions/MessageBusExtensionsTests.cs +278 -0
- package/Tests/Runtime/Core/Extensions/MessageBusExtensionsTests.cs.meta +11 -0
- package/Tests/Runtime/Core/Extensions/MessageExtensionsProviderTests.cs +289 -0
- package/Tests/Runtime/Core/Extensions/MessageExtensionsProviderTests.cs.meta +11 -0
- package/Tests/Runtime/Core/Extensions.meta +8 -0
- package/Tests/Runtime/Core/IntegrationShimSmokeTests.cs +57 -0
- package/Tests/Runtime/Core/IntegrationShimSmokeTests.cs.meta +11 -0
- package/Tests/Runtime/Core/MessageHandlerGlobalBusTests.cs +219 -0
- package/Tests/Runtime/Core/MessageHandlerGlobalBusTests.cs.meta +11 -0
- package/Tests/Runtime/Core/MessageRegistrationBuilderTests.cs +204 -0
- package/Tests/Runtime/Core/MessageRegistrationBuilderTests.cs.meta +11 -0
- package/Tests/Runtime/Core/MessagingTestBase.cs +4 -4
- package/Tests/Runtime/Core/NominalTests.cs +2 -2
- package/Tests/Runtime/Core/SourceGeneratorNestedTests.cs +1 -1
- package/Tests/Runtime/Core/TypedShorthandTests.cs +2 -2
- package/Tests/Runtime/Core/UntargetedEquivalenceTests.cs +1 -1
- package/Tests/Runtime/Core/UntargetedPrefreezeTests.cs +2 -4
- package/Tests/Runtime/Integrations/Reflex/ReflexIntegrationTests.cs +162 -0
- package/Tests/Runtime/Integrations/Reflex/ReflexIntegrationTests.cs.meta +11 -0
- package/Tests/Runtime/Integrations/Reflex/Resources/ReflexSettings.asset +16 -0
- package/Tests/Runtime/Integrations/Reflex/Resources/ReflexSettings.asset.meta +8 -0
- package/Tests/Runtime/Integrations/Reflex/Resources.meta +8 -0
- package/Tests/Runtime/Integrations/Reflex/WallstopStudios.DxMessaging.Tests.Runtime.Reflex.asmdef +27 -0
- package/Tests/Runtime/Integrations/Reflex/WallstopStudios.DxMessaging.Tests.Runtime.Reflex.asmdef.meta +7 -0
- package/Tests/Runtime/Integrations/Reflex.meta +8 -0
- package/Tests/Runtime/Integrations/VContainer/VContainerIntegrationTests.cs +140 -0
- package/Tests/Runtime/Integrations/VContainer/VContainerIntegrationTests.cs.meta +11 -0
- package/Tests/Runtime/Integrations/VContainer/WallstopStudios.DxMessaging.Tests.Runtime.VContainer.asmdef +37 -0
- package/Tests/Runtime/Integrations/VContainer/WallstopStudios.DxMessaging.Tests.Runtime.VContainer.asmdef.meta +7 -0
- package/Tests/Runtime/Integrations/VContainer.meta +8 -0
- package/Tests/Runtime/Integrations/Zenject/WallstopStudios.DxMessaging.Tests.Runtime.Zenject.asmdef +37 -0
- package/Tests/Runtime/Integrations/Zenject/WallstopStudios.DxMessaging.Tests.Runtime.Zenject.asmdef.meta +7 -0
- package/Tests/Runtime/Integrations/Zenject/ZenjectIntegrationTests.cs +140 -0
- package/Tests/Runtime/Integrations/Zenject/ZenjectIntegrationTests.cs.meta +11 -0
- package/Tests/Runtime/Integrations/Zenject.meta +8 -0
- package/Tests/Runtime/Integrations.meta +8 -0
- package/Tests/Runtime/Scripts/Components/EmptyMessageAwareComponent.cs +1 -1
- package/Tests/Runtime/Scripts/Components/GenericMessageAwareComponent.cs +1 -1
- package/Tests/Runtime/Scripts/Components/SimpleMessageAwareComponent.cs +1 -1
- package/Tests/Runtime/TestUtilities/UnityFixtureBase.cs +64 -0
- package/Tests/Runtime/TestUtilities/UnityFixtureBase.cs.meta +12 -0
- package/Tests/Runtime/TestUtilities.meta +9 -0
- package/Tests/Runtime/Unity/MessageBusProviderAssetTests.cs +57 -0
- package/Tests/Runtime/Unity/MessageBusProviderAssetTests.cs.meta +11 -0
- package/Tests/Runtime/Unity/MessageBusProviderHandleTests.cs +107 -0
- package/Tests/Runtime/Unity/MessageBusProviderHandleTests.cs.meta +12 -0
- package/Tests/Runtime/Unity/MessagingComponentProviderIntegrationTests.cs +210 -0
- package/Tests/Runtime/Unity/MessagingComponentProviderIntegrationTests.cs.meta +12 -0
- package/Tests/Runtime/Unity.meta +9 -0
- package/Tests/Runtime/WallstopStudios.DxMessaging.Tests.Runtime.asmdef +3 -1
- package/package.json +1 -1
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
# Runtime Message Bus Configuration
|
|
2
|
+
|
|
3
|
+
This guide covers how to configure message buses at runtime and retarget existing registrations. These features enable advanced scenarios like dependency injection, testing with isolated buses, and dynamic reconfiguration of messaging hierarchies.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Runtime Message Bus Configuration](#runtime-message-bus-configuration)
|
|
8
|
+
- [When You Need This](#when-you-need-this)
|
|
9
|
+
- [Global Message Bus Management](#global-message-bus-management)
|
|
10
|
+
- [Re-binding Registrations](#re-binding-registrations)
|
|
11
|
+
- [Common Patterns](#common-patterns)
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## When You Need This
|
|
16
|
+
|
|
17
|
+
You'll use runtime configuration when you need to:
|
|
18
|
+
|
|
19
|
+
- **Integrate with DI containers** — Replace the global bus with a container-managed instance
|
|
20
|
+
- **Isolate tests** — Ensure each test uses its own bus to prevent interference
|
|
21
|
+
- **Support multiple game modes** — Use different buses for different gameplay contexts (e.g., main game vs. mini-games)
|
|
22
|
+
- **Dynamically reconfigure components** — Change which bus a component listens to after it's been created
|
|
23
|
+
|
|
24
|
+
If you're just getting started with DxMessaging, you probably don't need these features yet. The default global bus works great for most scenarios.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Global Message Bus Management
|
|
29
|
+
|
|
30
|
+
By default, DxMessaging creates a single process-wide message bus during static initialization. This bus is available through `MessageHandler.MessageBus` and works great for most scenarios.
|
|
31
|
+
|
|
32
|
+
### Replacing the Global Bus
|
|
33
|
+
|
|
34
|
+
Use `SetGlobalMessageBus()` when you want to permanently replace the default bus:
|
|
35
|
+
|
|
36
|
+
```csharp
|
|
37
|
+
using DxMessaging.Core;
|
|
38
|
+
using DxMessaging.Core.MessageBus;
|
|
39
|
+
|
|
40
|
+
// Create a custom bus (often from a DI container)
|
|
41
|
+
IMessageBus customBus = new MessageBus();
|
|
42
|
+
|
|
43
|
+
// Replace the global bus
|
|
44
|
+
MessageHandler.SetGlobalMessageBus(customBus);
|
|
45
|
+
|
|
46
|
+
// All new registrations will now use customBus
|
|
47
|
+
var handler = new MessageHandler(new InstanceId(1)) { active = true };
|
|
48
|
+
// handler.MessageBus is now customBus
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
#### When to use this
|
|
52
|
+
|
|
53
|
+
- During application startup when integrating with DI containers
|
|
54
|
+
- When you want all message traffic to flow through a specific bus instance
|
|
55
|
+
- In integration tests that need complete control over message routing
|
|
56
|
+
|
|
57
|
+
**Important:** This permanently replaces the global bus for the lifetime of the application. All subsequent registrations will use the new bus unless explicitly configured otherwise.
|
|
58
|
+
|
|
59
|
+
### Temporarily Overriding the Global Bus
|
|
60
|
+
|
|
61
|
+
Use `OverrideGlobalMessageBus()` when you want to temporarily replace the bus and automatically restore it later:
|
|
62
|
+
|
|
63
|
+
```csharp
|
|
64
|
+
IMessageBus originalBus = MessageHandler.MessageBus;
|
|
65
|
+
IMessageBus temporaryBus = new MessageBus();
|
|
66
|
+
|
|
67
|
+
// Temporarily override
|
|
68
|
+
using (MessageHandler.OverrideGlobalMessageBus(temporaryBus))
|
|
69
|
+
{
|
|
70
|
+
// Inside this scope, MessageHandler.MessageBus returns temporaryBus
|
|
71
|
+
Assert.AreSame(temporaryBus, MessageHandler.MessageBus);
|
|
72
|
+
|
|
73
|
+
// Any message handlers created here use temporaryBus
|
|
74
|
+
var msg = new MyMessage();
|
|
75
|
+
msg.EmitUntargeted(); // Goes to temporaryBus
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Outside the scope, the original bus is restored
|
|
79
|
+
Assert.AreSame(originalBus, MessageHandler.MessageBus);
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
#### When to use this
|
|
83
|
+
|
|
84
|
+
- In unit tests to isolate message traffic
|
|
85
|
+
- When temporarily redirecting messages for debugging or logging
|
|
86
|
+
- For scoped gameplay features that need their own message channel
|
|
87
|
+
|
|
88
|
+
**Pattern:** This returns an `IDisposable`, so you can use it with `using` statements for automatic cleanup. When the scope exits (either normally or via exception), the previous bus is restored.
|
|
89
|
+
|
|
90
|
+
### Resetting to the Default Bus
|
|
91
|
+
|
|
92
|
+
Use `ResetGlobalMessageBus()` to restore the original startup bus:
|
|
93
|
+
|
|
94
|
+
```csharp
|
|
95
|
+
// Replace the global bus
|
|
96
|
+
MessageHandler.SetGlobalMessageBus(containerBus);
|
|
97
|
+
|
|
98
|
+
// Later, restore the original default bus
|
|
99
|
+
MessageHandler.ResetGlobalMessageBus();
|
|
100
|
+
|
|
101
|
+
// MessageHandler.MessageBus is now back to the original startup bus
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
#### When to use this
|
|
105
|
+
|
|
106
|
+
- After tests that called `SetGlobalMessageBus()`
|
|
107
|
+
- When tearing down a DI container and reverting to default behavior
|
|
108
|
+
- In development/debug scenarios where you want to reset state
|
|
109
|
+
|
|
110
|
+
### Accessing the Original Startup Bus
|
|
111
|
+
|
|
112
|
+
`MessageHandler.InitialGlobalMessageBus` always returns the original bus that was created during static initialization, regardless of any calls to `SetGlobalMessageBus()`:
|
|
113
|
+
|
|
114
|
+
```csharp
|
|
115
|
+
IMessageBus startupBus = MessageHandler.InitialGlobalMessageBus;
|
|
116
|
+
|
|
117
|
+
// Replace the global bus
|
|
118
|
+
MessageHandler.SetGlobalMessageBus(new MessageBus());
|
|
119
|
+
|
|
120
|
+
// InitialGlobalMessageBus is unchanged
|
|
121
|
+
Assert.AreSame(startupBus, MessageHandler.InitialGlobalMessageBus);
|
|
122
|
+
|
|
123
|
+
// But MessageBus returns the new bus
|
|
124
|
+
Assert.AreNotSame(startupBus, MessageHandler.MessageBus);
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
#### When to use this
|
|
128
|
+
|
|
129
|
+
- In diagnostic tools that need a stable reference point
|
|
130
|
+
- When you want to compare against the original bus for debugging
|
|
131
|
+
- In tests that need to verify bus isolation while still accessing the original
|
|
132
|
+
|
|
133
|
+
### Example: Bootstrapping a DI Container
|
|
134
|
+
|
|
135
|
+
Here's a complete example of integrating DxMessaging with a DI container:
|
|
136
|
+
|
|
137
|
+
```csharp
|
|
138
|
+
using DxMessaging.Core;
|
|
139
|
+
using DxMessaging.Core.MessageBus;
|
|
140
|
+
|
|
141
|
+
public class GameBootstrapper
|
|
142
|
+
{
|
|
143
|
+
public void Bootstrap()
|
|
144
|
+
{
|
|
145
|
+
// Create container-managed bus
|
|
146
|
+
IMessageBus containerBus = new MessageBus();
|
|
147
|
+
|
|
148
|
+
// Register with container
|
|
149
|
+
container.RegisterInstance<IMessageBus>(containerBus);
|
|
150
|
+
|
|
151
|
+
// Replace global bus so all subsequent registrations use it
|
|
152
|
+
MessageHandler.SetGlobalMessageBus(containerBus);
|
|
153
|
+
|
|
154
|
+
// Now when MessagingComponents are created, they automatically
|
|
155
|
+
// use the container-managed bus
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Re-binding Registrations
|
|
163
|
+
|
|
164
|
+
Sometimes you need to change which bus a component listens to after it's already been set up. This is called "re-binding."
|
|
165
|
+
|
|
166
|
+
### The MessageBusRebindMode Enum
|
|
167
|
+
|
|
168
|
+
When re-binding, you have two options:
|
|
169
|
+
|
|
170
|
+
#### PreserveRegistrations
|
|
171
|
+
|
|
172
|
+
Keeps existing active registrations on their current bus, but sets the specified bus for future registrations:
|
|
173
|
+
|
|
174
|
+
```csharp
|
|
175
|
+
// Component is currently using busA
|
|
176
|
+
component.Configure(busA, MessageBusRebindMode.RebindActive);
|
|
177
|
+
|
|
178
|
+
// Later, switch to busB but preserve existing registrations
|
|
179
|
+
component.Configure(busB, MessageBusRebindMode.PreserveRegistrations);
|
|
180
|
+
|
|
181
|
+
// Existing handlers still listen on busA
|
|
182
|
+
// New registrations will use busB
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
##### When to use this
|
|
186
|
+
|
|
187
|
+
- When you want to gradually migrate a component to a new bus
|
|
188
|
+
- If you need to maintain backwards compatibility during refactoring
|
|
189
|
+
- When existing registrations must continue processing messages from their original source
|
|
190
|
+
|
|
191
|
+
#### RebindActive
|
|
192
|
+
|
|
193
|
+
Immediately moves all active registrations to the new bus:
|
|
194
|
+
|
|
195
|
+
```csharp
|
|
196
|
+
// Component is listening on busA
|
|
197
|
+
component.Configure(busA, MessageBusRebindMode.RebindActive);
|
|
198
|
+
|
|
199
|
+
// Switch everything to busB
|
|
200
|
+
component.Configure(busB, MessageBusRebindMode.RebindActive);
|
|
201
|
+
|
|
202
|
+
// All handlers now listen on busB
|
|
203
|
+
// busA handlers are deregistered and re-registered on busB
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
##### When to use this
|
|
207
|
+
|
|
208
|
+
- When you want complete, immediate migration to a new bus
|
|
209
|
+
- In DI scenarios where the container provides a new bus instance
|
|
210
|
+
- When you need atomic switching without mixed-bus behavior
|
|
211
|
+
|
|
212
|
+
### Retarget a Token Directly
|
|
213
|
+
|
|
214
|
+
You can also retarget individual `MessageRegistrationToken` instances:
|
|
215
|
+
|
|
216
|
+
```csharp
|
|
217
|
+
using DxMessaging.Core;
|
|
218
|
+
using DxMessaging.Core.MessageBus;
|
|
219
|
+
|
|
220
|
+
IMessageBus busA = new MessageBus();
|
|
221
|
+
IMessageBus busB = new MessageBus();
|
|
222
|
+
|
|
223
|
+
var handler = new MessageHandler(new InstanceId(1), busA) { active = true };
|
|
224
|
+
var token = MessageRegistrationToken.Create(handler, busA);
|
|
225
|
+
token.RegisterUntargeted<MyMessage>(OnMessage);
|
|
226
|
+
token.Enable();
|
|
227
|
+
|
|
228
|
+
// Later, retarget to busB
|
|
229
|
+
token.RetargetMessageBus(busB, MessageBusRebindMode.RebindActive);
|
|
230
|
+
|
|
231
|
+
// All registrations are now on busB
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
#### When to use this
|
|
235
|
+
|
|
236
|
+
- When you have direct access to a token and want fine-grained control
|
|
237
|
+
- In advanced scenarios like dynamic message routing or pooling
|
|
238
|
+
- When building custom messaging abstractions
|
|
239
|
+
|
|
240
|
+
### Example: Scene-Specific Buses
|
|
241
|
+
|
|
242
|
+
Here's a practical example of using re-binding for scene isolation:
|
|
243
|
+
|
|
244
|
+
```csharp
|
|
245
|
+
using DxMessaging.Core.MessageBus;
|
|
246
|
+
using DxMessaging.Unity;
|
|
247
|
+
using UnityEngine;
|
|
248
|
+
|
|
249
|
+
public class SceneMessagingManager : MonoBehaviour
|
|
250
|
+
{
|
|
251
|
+
private IMessageBus _sceneLocalBus;
|
|
252
|
+
|
|
253
|
+
private void Awake()
|
|
254
|
+
{
|
|
255
|
+
// Create a bus specific to this scene
|
|
256
|
+
_sceneLocalBus = new MessageBus();
|
|
257
|
+
|
|
258
|
+
// Find all messaging components in this scene
|
|
259
|
+
MessagingComponent[] components = FindObjectsOfType<MessagingComponent>();
|
|
260
|
+
|
|
261
|
+
// Retarget them to the scene-local bus
|
|
262
|
+
foreach (var component in components)
|
|
263
|
+
{
|
|
264
|
+
component.Configure(_sceneLocalBus, MessageBusRebindMode.RebindActive);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
private void OnDestroy()
|
|
269
|
+
{
|
|
270
|
+
// When scene unloads, components are destroyed automatically
|
|
271
|
+
// No need to manually clean up registrations
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
#### Why this is useful
|
|
277
|
+
|
|
278
|
+
- Messages sent in this scene won't leak to other scenes
|
|
279
|
+
- When the scene unloads, all message traffic stops cleanly
|
|
280
|
+
- Perfect for additive scene workflows or mini-games
|
|
281
|
+
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
## Common Patterns
|
|
285
|
+
|
|
286
|
+
### Pattern 1: Test Isolation
|
|
287
|
+
|
|
288
|
+
Ensure each test has its own isolated bus:
|
|
289
|
+
|
|
290
|
+
```csharp
|
|
291
|
+
using NUnit.Framework;
|
|
292
|
+
using DxMessaging.Core;
|
|
293
|
+
using DxMessaging.Core.MessageBus;
|
|
294
|
+
|
|
295
|
+
[TestFixture]
|
|
296
|
+
public class MySystemTests
|
|
297
|
+
{
|
|
298
|
+
private IMessageBus _testBus;
|
|
299
|
+
|
|
300
|
+
[SetUp]
|
|
301
|
+
public void SetUp()
|
|
302
|
+
{
|
|
303
|
+
// Create a fresh bus for each test
|
|
304
|
+
_testBus = new MessageBus();
|
|
305
|
+
MessageHandler.SetGlobalMessageBus(_testBus);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
[TearDown]
|
|
309
|
+
public void TearDown()
|
|
310
|
+
{
|
|
311
|
+
// Restore the default bus
|
|
312
|
+
MessageHandler.ResetGlobalMessageBus();
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
[Test]
|
|
316
|
+
public void MyTest()
|
|
317
|
+
{
|
|
318
|
+
// This test uses _testBus exclusively
|
|
319
|
+
// No interference from other tests
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### Pattern 2: Temporary Override with Automatic Cleanup
|
|
325
|
+
|
|
326
|
+
Use `using` statements for scoped overrides:
|
|
327
|
+
|
|
328
|
+
```csharp
|
|
329
|
+
[Test]
|
|
330
|
+
public void TestWithIsolation()
|
|
331
|
+
{
|
|
332
|
+
IMessageBus isolatedBus = new MessageBus();
|
|
333
|
+
|
|
334
|
+
using (MessageHandler.OverrideGlobalMessageBus(isolatedBus))
|
|
335
|
+
{
|
|
336
|
+
// Test code here uses isolatedBus
|
|
337
|
+
var msg = new TestMessage();
|
|
338
|
+
msg.EmitUntargeted();
|
|
339
|
+
|
|
340
|
+
// Verify only this test's bus received the message
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// Original bus automatically restored
|
|
344
|
+
}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### Pattern 3: DI Container Integration
|
|
348
|
+
|
|
349
|
+
Bootstrap with container-managed bus:
|
|
350
|
+
|
|
351
|
+
```csharp
|
|
352
|
+
public class DependencyInjectionBootstrap
|
|
353
|
+
{
|
|
354
|
+
public void Initialize(IContainer container)
|
|
355
|
+
{
|
|
356
|
+
// Container creates the bus
|
|
357
|
+
IMessageBus containerBus = container.Resolve<IMessageBus>();
|
|
358
|
+
|
|
359
|
+
// Make it the global default
|
|
360
|
+
MessageHandler.SetGlobalMessageBus(containerBus);
|
|
361
|
+
|
|
362
|
+
// Now all MessagingComponents use the container bus by default
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
### Pattern 4: Dynamic Component Reconfiguration
|
|
368
|
+
|
|
369
|
+
Change a component's bus at runtime:
|
|
370
|
+
|
|
371
|
+
```csharp
|
|
372
|
+
public class DynamicComponentManager
|
|
373
|
+
{
|
|
374
|
+
public void SwitchComponentToBus(MessagingComponent component, IMessageBus newBus)
|
|
375
|
+
{
|
|
376
|
+
// Immediately move all handlers to the new bus
|
|
377
|
+
component.Configure(newBus, MessageBusRebindMode.RebindActive);
|
|
378
|
+
|
|
379
|
+
// Component now listens on newBus
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
---
|
|
385
|
+
|
|
386
|
+
## Quick Reference
|
|
387
|
+
|
|
388
|
+
| API | Purpose | Use Case |
|
|
389
|
+
| ---------------------------------------------- | ------------------------------------------ | ------------------------------- |
|
|
390
|
+
| `MessageHandler.MessageBus` | Access current global bus | Normal message emission |
|
|
391
|
+
| `MessageHandler.InitialGlobalMessageBus` | Access original startup bus | Diagnostics, debugging |
|
|
392
|
+
| `MessageHandler.SetGlobalMessageBus(bus)` | Permanently replace global bus | DI integration, test setup |
|
|
393
|
+
| `MessageHandler.OverrideGlobalMessageBus(bus)` | Temporarily override (returns IDisposable) | Test isolation, scoped features |
|
|
394
|
+
| `MessageHandler.ResetGlobalMessageBus()` | Restore original startup bus | Test teardown, reset state |
|
|
395
|
+
| `component.Configure(bus, mode)` | Set component's bus | Component configuration |
|
|
396
|
+
| `token.RetargetMessageBus(bus, mode)` | Retarget a token | Fine-grained control |
|
|
397
|
+
| `MessageBusRebindMode.PreserveRegistrations` | Keep existing registrations on old bus | Gradual migration |
|
|
398
|
+
| `MessageBusRebindMode.RebindActive` | Move all registrations to new bus | Atomic switching |
|
|
399
|
+
|
|
400
|
+
---
|
|
401
|
+
|
|
402
|
+
## See Also
|
|
403
|
+
|
|
404
|
+
- **[Message Bus Providers](MessageBusProviders.md)** — ScriptableObject-based provider system for design-time configuration
|
|
405
|
+
- **[DI Integration Guides](Integrations/)** — Zenject, VContainer, and Reflex integration patterns
|
|
406
|
+
- **[Testing Guide](Testing.md)** — Comprehensive testing patterns with DxMessaging
|
|
407
|
+
- **[Back to Documentation Hub](Index.md)** — Browse all docs
|
package/Docs/UnityIntegration.md
CHANGED
|
@@ -5,7 +5,8 @@ Unity‑centric helpers make registration lifecycles explicit and safe.
|
|
|
5
5
|
MessagingComponent
|
|
6
6
|
|
|
7
7
|
- Attach to any GameObject that will send or receive messages.
|
|
8
|
-
- Creates a per
|
|
8
|
+
- Creates a per-owner `MessageHandler` and offers `Create(this)` to get a `MessageRegistrationToken`.
|
|
9
|
+
- Call `Configure(IMessageBus, MessageBusRebindMode)` before `Create` if you want the component to use a custom bus (e.g., one resolved from a DI container). Passing `MessageBusRebindMode.RebindActive` migrates current registrations; `PreserveRegistrations` defers the swap until the next enable.
|
|
9
10
|
- Optional: set `emitMessagesWhenDisabled` if you need to emit while disabled.
|
|
10
11
|
|
|
11
12
|
MessageAwareComponent
|
|
@@ -13,6 +14,7 @@ MessageAwareComponent
|
|
|
13
14
|
- Derive for a batteries‑included pattern; it manages a token for you.
|
|
14
15
|
- Override `RegisterMessageHandlers()` to stage registrations.
|
|
15
16
|
- The token is enabled/disabled with the component’s enable state.
|
|
17
|
+
- Call `ConfigureMessageBus(IMessageBus, MessageBusRebindMode)` before `base.Awake()` (or shortly after via a DI bootstrapper) to ensure the token is created against your container-provided bus.
|
|
16
18
|
|
|
17
19
|
```csharp
|
|
18
20
|
using DxMessaging.Unity;
|