public async Task UpdateAmount(string id, int amount)
        {
            var @event = await CreateEvent(id, EventTypes.AmountUpdated, amount);

            var amountUpdated = AmountUpdated.Create(@event, id, amount);

            messageQueue.Publish(amountUpdated);
        }
        IMessage <object> ConstructMessage <T>(Event @event)
        {
            var data = @event.Data;

            if (data == null)
            {
                throw new ArgumentNullException(nameof(@event.Data));
            }

            switch (data.Type)
            {
            case EventTypes.AmountUpdated:
                var amount = data.Payload as int?;
                if (amount != null)
                {
                    return((IMessage <object>)AmountUpdated.Create(@event, data.Id, amount.Value));
                }
                break;

            case EventTypes.ProductCreated:
                if (data.Payload is Product product)
                {
                    return((IMessage <object>)ProductCreated.Create(@event, product));
                }
                break;

            case EventTypes.ProductDeleted:
                return((IMessage <object>)ProductDeleted.Create(@event, data.Id));

            case EventTypes.TitleUpdated:
                var title = data.Payload as string;
                return((IMessage <object>)TitleUpdated.Create(@event, data.Id, title));

            default:
                break;
            }

            throw new ArgumentException($"InvalidEvent data: {data.Id}, " +
                                        $"{data.Type}, {data.Payload}");
        }