public override async Task PublishMessageAsync(IMessage message, CancellationToken cancellationToken) { if (message is IDomainEvent domainEvent && _pubModule.HasChannel(message.GetType())) { ChannelMeta channel = _pubModule.GetChannel(domainEvent.GetType()); IDatabase database = _connModule.GetDatabase(channel.DatabaseName); // Only publish the domain-event if it passes the predicate associated // with the channel: if (!channel.Applies(domainEvent)) { return; } byte[] messageValue = _serialization.Serialize(domainEvent, channel.ContentType); // Build the name of the channel to publish to by combining the static channel // name with the optional event state data. string eventStateData = channel.GetEventStateData(domainEvent); string channelName = $"{channel.ChannelName}.{eventStateData}"; LogChannelPublish(domainEvent, channel.DatabaseName, channelName); byte[] messageData = ChannelMessageEncoder.Pack(channel.ContentType, messageValue); await database.PublishAsync(channelName, messageData).ConfigureAwait(false); } }
public async Task SubscribeAsync <TDomainEvent>(string database, string channel, Action <TDomainEvent> handler) where TDomainEvent : IDomainEvent { if (string.IsNullOrWhiteSpace(channel)) { throw new ArgumentException("Channel not specified.", nameof(channel)); } if (handler == null) { throw new ArgumentNullException(nameof(handler)); } var subscriber = _connModule.GetSubscriber(database); await subscriber.SubscribeAsync(channel, (onChannel, message) => { var messageParts = ChannelMessageEncoder.UnPack(message); TDomainEvent domainEvent = _serializationMgr.Deserialize <TDomainEvent>( messageParts.contentType, messageParts.messageData); LogReceivedDomainEvent(database, channel, domainEvent); handler(domainEvent); }).ConfigureAwait(false); }
private async Task SubscribeToChannels(IEnumerable <MessageChannelSubscriber> subscribers) { foreach (var msgSubscriber in subscribers) { ISubscriber subscriber = ConnModule.GetSubscriber(msgSubscriber.DatabaseName); // Callback invoked when message published to channel: await subscriber.SubscribeAsync(msgSubscriber.Channel, (channel, message) => { Type messageType = msgSubscriber.DispatchInfo.MessageType; var messageParts = ChannelMessageEncoder.UnPack(message); // Deserialize message byte array into domain-event type associated with handler: IDomainEvent domainEvent = (IDomainEvent)_serializationManager.Deserialize( messageParts.contentType, messageType, messageParts.messageData); LogReceivedDomainEvent(channel, domainEvent, msgSubscriber); // Invoke the in-process handler: DispatchModule.InvokeDispatcherInNewLifetimeScopeAsync( msgSubscriber.DispatchInfo, domainEvent).Wait(); }); } }