Goal
Replace the hardcoded switch/case in TcpSyncServer.HandleClientAsync with a dictionary-based handler registry (IDictionary<MessageType, IMessageHandler>), registered via Dependency Injection.
Motivation
TcpSyncServer currently contains a monolithic switch/case with ~15 cases inline. Every new message type requires editing TcpSyncServer directly. With a handler registry, a new service (e.g. notifications, metrics push) only needs to register its own IMessageHandler implementation — zero changes to TcpSyncServer.
Proposed design
IMessageHandler interface
csharp public interface IMessageHandler { MessageType MessageType { get; } Task HandleAsync(SyncContext context, CancellationToken cancellationToken); }
SyncContext
csharp public record SyncContext( int MessageType, byte[] Payload, string PeerId, TcpPeerClient Client );
DI registration
`csharp
services.AddSingleton<IMessageHandler, GetClockHandler>();
services.AddSingleton<IMessageHandler, PullChangesHandler>();
// ...
// Build registry
services.AddSingleton<IDictionary<MessageType, IMessageHandler>>(sp =>
sp.GetServices()
.ToDictionary(h => h.MessageType));
`
TcpSyncServer dispatch
csharp var (msgType, payload) = await _protocol.ReadMessageAsync(stream, ct); if (!_handlers.TryGetValue(msgType, out var handler)) { _logger.LogWarning("Unknown message type {Type}", msgType); return; } await handler.HandleAsync(new SyncContext(msgType, payload, peerId, client), ct);
Acceptance criteria
- TcpSyncServer contains no message-type-specific logic
- All existing handlers are extracted into individual classes
- All tests pass, build is error-free
- Adding a new handler requires: implement IMessageHandler, register in DI — no other changes
Goal
Replace the hardcoded switch/case in TcpSyncServer.HandleClientAsync with a dictionary-based handler registry (IDictionary<MessageType, IMessageHandler>), registered via Dependency Injection.
Motivation
TcpSyncServer currently contains a monolithic switch/case with ~15 cases inline. Every new message type requires editing TcpSyncServer directly. With a handler registry, a new service (e.g. notifications, metrics push) only needs to register its own IMessageHandler implementation — zero changes to TcpSyncServer.
Proposed design
IMessageHandler interface
csharp public interface IMessageHandler { MessageType MessageType { get; } Task HandleAsync(SyncContext context, CancellationToken cancellationToken); }SyncContext
csharp public record SyncContext( int MessageType, byte[] Payload, string PeerId, TcpPeerClient Client );DI registration
`csharp
services.AddSingleton<IMessageHandler, GetClockHandler>();
services.AddSingleton<IMessageHandler, PullChangesHandler>();
// ...
// Build registry
services.AddSingleton<IDictionary<MessageType, IMessageHandler>>(sp =>
sp.GetServices()
.ToDictionary(h => h.MessageType));
`
TcpSyncServer dispatch
csharp var (msgType, payload) = await _protocol.ReadMessageAsync(stream, ct); if (!_handlers.TryGetValue(msgType, out var handler)) { _logger.LogWarning("Unknown message type {Type}", msgType); return; } await handler.HandleAsync(new SyncContext(msgType, payload, peerId, client), ct);Acceptance criteria