/// <summary> /// Creates a channel for the purpose of consuming messages /// </summary> /// <typeparam name="T">The type of message to consume</typeparam> /// <param name="exchange">The associated RabbitMQ exchange</param> /// <param name="queue">The associated RabbitMQ queue</param> /// <param name="autoDelete">True if the underlying queue should be deleted when the channel is closed</param> /// <param name="exclusive">True if the underlying queue should only be accessible from the new channel</param> /// <returns>The opened consumer channel</returns> /// <remarks> /// This method actually performs some optimization by realizing that we can have a single channel per RabbitMQ /// endpoint. /// Instead of opening multiple channels to the same queue (or multiple publish channels) we can reuse the existing /// channel. /// This appears to be thread-safe in my testing. Opening and closing channels adds considerable overhead, so resuing /// the /// existing channel adds a considerable performance improvement. /// </remarks> public RabbitMQConsumerChannel OpenConsumerChannel(string exchange, string queue, bool autoDelete = false, bool exclusive = true) { // we do not want to create a new channel unless the requested channel does not exist var channel = Channels .SingleOrDefault(c => c.AutoDelete == autoDelete && c.Exclusive == exclusive && c.GetType().IsAssignableFrom(typeof(RabbitMQConsumerChannel)) ); if (channel == null) { channel = new RabbitMQConsumerChannel(this, _container, exchange, queue, autoDelete, exclusive); Channels.Add(channel); } return((RabbitMQConsumerChannel)channel); }
/// <summary> /// Construct a consumer for the specified channel /// </summary> /// <param name="channel">The associated channel for this consumer</param> /// <param name="container">The AutoFac container for registering MediatR handlers</param> public RabbitMQConsumer(RabbitMQConsumerChannel channel, IContainer container) : base(channel.Model) { Channel = channel; _container = container; Received += RabbitMQConsumer_Received; }