public IEnumerable <IMessagePump> CreateAll()
        {
            var openGenericHandlerType = typeof(IHandleMulticastRequest <,>);
            var handlerTypes           = _typeProvider.MulticastRequestHandlerTypes.ToArray();

            // Events are routed to Topics and we'll create a competing subscription for the logical endpoint
            var allMessageTypesHandledByThisEndpoint = _handlerMapper.GetMessageTypesHandledBy(openGenericHandlerType, handlerTypes);
            var bindings = allMessageTypesHandledByThisEndpoint
                           .Select(m => new { MessageType = m, TopicPath = _router.Route(m, QueueOrTopic.Topic, _pathFactory) })
                           .GroupBy(b => b.TopicPath)
                           .Select(g => new
            {
                TopicPath    = g.Key,
                MessageTypes = g.Select(x => x.MessageType),
                HandlerTypes = g.SelectMany(x => _handlerMapper.GetHandlerTypesFor(openGenericHandlerType, x.MessageType))
            })
                           .ToArray();

            if (bindings.Any(b => b.MessageTypes.Count() > 1))
            {
                throw new NotSupportedException("Routing multiple message types through a single Topic is not supported.");
            }

            foreach (var binding in bindings)
            {
                foreach (var handlerType in binding.HandlerTypes)
                {
                    var messageType      = binding.MessageTypes.Single();
                    var subscriptionName = _pathFactory.SubscriptionNameFor(_applicationName, handlerType);
                    var filterCondition  = _filterConditionProvider.GetFilterConditionFor(handlerType);

                    _logger.Debug("Creating message pump for multicast request subscription '{0}/{1}' handling {2} with filter {3}",
                                  binding.TopicPath,
                                  subscriptionName,
                                  messageType,
                                  filterCondition);

                    var messageReceiver = _transport.GetTopicReceiver(binding.TopicPath, subscriptionName, filterCondition);
                    var handlerMap      = new Dictionary <Type, Type[]> {
                        { messageType, new[] { handlerType } }
                    };
                    var messageDispatcher = _messageDispatcherFactory.Create(openGenericHandlerType, handlerMap);

                    var pump = _container.ResolveWithOverrides <MessagePump>(messageReceiver, messageDispatcher);
                    GarbageMan.Add(pump);
                    yield return(pump);
                }
            }
        }
        public IEnumerable <IMessagePump> CreateAll()
        {
            var openGenericHandlerType = typeof(IHandleMulticastEvent <>);
            var handlerTypes           = _typeProvider.MulticastEventHandlerTypes.ToArray();

            // Events are routed to Topics and we'll create a subscription per instance of the logical endpoint to enable multicast behaviour
            var allMessageTypesHandledByThisEndpoint = _handlerMapper.GetMessageTypesHandledBy(openGenericHandlerType, handlerTypes);
            var bindings = allMessageTypesHandledByThisEndpoint
                           .Select(m => new { MessageType = m, TopicPath = _router.Route(m, QueueOrTopic.Topic) })
                           .GroupBy(b => b.TopicPath)
                           .Select(g => new
            {
                TopicPath    = g.Key,
                MessageTypes = g.Select(x => x.MessageType),
                HandlerTypes = g.SelectMany(x => _handlerMapper.GetHandlerTypesFor(openGenericHandlerType, x.MessageType))
            })
                           .ToArray();

            if (bindings.Any(b => b.MessageTypes.Count() > 1))
            {
                throw new NotSupportedException("Routing multiple message types through a single Topic is not supported.");
            }

            foreach (var binding in bindings)
            {
                foreach (var handlerType in binding.HandlerTypes)
                {
                    var messageType      = binding.MessageTypes.Single();
                    var subscriptionName = PathFactory.SubscriptionNameFor(_applicationName, _instanceName, handlerType);

                    _logger.Debug("Creating message pump for multicast event subscription '{0}/{1}' handling {2}", binding.TopicPath, subscriptionName, messageType);
                    var messageReceiver = _messagingFactory.GetTopicReceiver(binding.TopicPath, subscriptionName);

                    var handlerMap = new Dictionary <Type, Type[]> {
                        { messageType, new[] { handlerType } }
                    };
                    var pump = new MessagePump(_clock,
                                               _dispatchContextManager,
                                               _logger,
                                               _messageDispatcherFactory.Create(openGenericHandlerType, handlerMap),
                                               messageReceiver,
                                               _taskFactory);
                    _garbageMan.Add(pump);

                    yield return(pump);
                }
            }
        }
예제 #3
0
        public IEnumerable <IMessagePump> CreateAll()
        {
            var openGenericHandlerType = typeof(IHandleRequest <,>);
            var handlerTypes           = _typeProvider.RequestHandlerTypes.ToArray();

            // Create a single connection to each request queue determined by routing
            var allMessageTypesHandledByThisEndpoint = _handlerMapper.GetMessageTypesHandledBy(openGenericHandlerType, handlerTypes);
            var bindings = allMessageTypesHandledByThisEndpoint
                           .Select(m => new { MessageType = m, QueuePath = _router.Route(m, QueueOrTopic.Queue, _pathFactory) })
                           .GroupBy(b => b.QueuePath)
                           .Select(g => new { QueuePath = g.Key, HandlerTypes = g.SelectMany(x => _handlerMapper.GetHandlerTypesFor(openGenericHandlerType, x.MessageType)) });

            // Each binding to a queue can handle one or more request types depending on the routes that are defined
            foreach (var binding in bindings)
            {
                var messageTypes = _handlerMapper.GetMessageTypesHandledBy(openGenericHandlerType, binding.HandlerTypes).ToArray();

                _logger.Debug("Creating message pump for request queue '{0}' handling {1}", binding.QueuePath, messageTypes.ToTypeNameSummary(selector: t => t.Name));

                var messageReceiver   = _transport.GetQueueReceiver(binding.QueuePath);
                var handlerMap        = _handlerMapper.GetHandlerMapFor(openGenericHandlerType, messageTypes);
                var messageDispatcher = _messageDispatcherFactory.Create(openGenericHandlerType, handlerMap);

                var pump = _container.ResolveWithOverrides <MessagePump>(messageReceiver, messageDispatcher);
                GarbageMan.Add(pump);
                yield return(pump);
            }
        }
예제 #4
0
        public IEnumerable <IMessagePump> CreateAll()
        {
            var openGenericHandlerType = typeof(IHandleCommand <>);
            var handlerTypes           = _typeProvider.CommandHandlerTypes.ToArray();

            // Create a single connection to each command queue determined by routing
            var allMessageTypesHandledByThisEndpoint = _handlerMapper.GetMessageTypesHandledBy(openGenericHandlerType, handlerTypes);
            var bindings = allMessageTypesHandledByThisEndpoint
                           .Select(m => new { MessageType = m, QueuePath = _router.Route(m, QueueOrTopic.Queue) })
                           .GroupBy(b => b.QueuePath)
                           .Select(g => new { QueuePath = g.Key, HandlerTypes = g.SelectMany(x => _handlerMapper.GetHandlerTypesFor(openGenericHandlerType, x.MessageType)) });

            // Each binding to a queue can handle one or more command types depending on the routes that are defined
            foreach (var binding in bindings)
            {
                var messageTypes = _handlerMapper.GetMessageTypesHandledBy(openGenericHandlerType, binding.HandlerTypes).ToArray();

                _logger.Debug("Creating message pump for command queue '{0}' handling {1}", binding.QueuePath, messageTypes.ToTypeNameSummary(selector: t => t.Name));
                var messageReceiver = _messagingFactory.GetQueueReceiver(binding.QueuePath);

                var handlerMap = _handlerMapper.GetHandlerMapFor(openGenericHandlerType, messageTypes);
                var pump       = new MessagePump(_clock,
                                                 _dispatchContextManager,
                                                 _logger,
                                                 _messageDispatcherFactory.Create(openGenericHandlerType, handlerMap),
                                                 messageReceiver,
                                                 _taskFactory);
                _garbageMan.Add(pump);

                yield return(pump);
            }
        }