private void OnReceived(MessageEnvelope<byte[]> envelope, IMessageAck ack)
        {
            try
            {
                var typeName = envelope.Properties.Type;
                typeName.AssertNotNullOrEmpty("typename was expected to be added to message properties");

                // PERF: needs caching
                var msgType = Type.GetType(typeName, throwOnError: true);

                Func<IMessageHandler> builder;
                if (!_message2HandlerBuilder.TryGetValue(msgType, out builder))
                {
                    var msg = "No IMessageHandler registered for message type " + msgType.FullName;
                    this.Logger.Error(msg);
                    throw new Exception(msg);
                }

                IMessageHandler handler = builder();

                var message = (IMessage) _bus.Serializer.Deserialize(envelope.Body, msgType);

                _invoker.Invoke(msgType, message, handler);

                ack.Ack();
            }
            catch (Exception e)
            {
                this.Logger.Error("Error processing message", e);

                ack.Reject(requeue: false);
            }
        }