Пример #1
0
 /// <summary>
 /// Enforce messaging rules. Make sure, the message can be used within the <see cref="IBus.Send(object[])"/>.
 /// </summary>
 /// <param name="messageType">Event, Command or message</param>
 /// <param name="messageIntent">The intent of the message</param>
 public static void AssertIsValidForSend(Type messageType, MessageIntentEnum messageIntent)
 {
     if (MessageConventionExtensions.IsEventType(messageType) && messageIntent != MessageIntentEnum.Publish)
     {
         throw new InvalidOperationException("Events can have multiple recipient so they should be published");
     }
 }
Пример #2
0
        void RegisterMessageOwnersAndBusAddress(IEnumerable <Type> knownMessages)
        {
            var unicastConfig = GetConfigSection <UnicastBusConfig>();
            var router        = new StaticMessageRouter(knownMessages);

            Configurer.RegisterSingleton <IRouteMessages>(router);

            if (unicastConfig == null)
            {
                return;
            }
            if (!string.IsNullOrWhiteSpace(unicastConfig.ForwardReceivedMessagesTo))
            {
                var forwardAddress = Address.Parse(unicastConfig.ForwardReceivedMessagesTo);
                busConfig.ConfigureProperty(b => b.ForwardReceivedMessagesTo, forwardAddress);
            }
            busConfig.ConfigureProperty(b => b.TimeToBeReceivedOnForwardedMessages, unicastConfig.TimeToBeReceivedOnForwardedMessages);

            var messageEndpointMappings = unicastConfig.MessageEndpointMappings.Cast <MessageEndpointMapping>()
                                          .OrderByDescending(m => m)
                                          .ToList();

            foreach (var mapping in messageEndpointMappings)
            {
                mapping.Configure((messageType, address) =>
                {
                    if (!MessageConventionExtensions.IsMessageType(messageType))
                    {
                        return;
                    }

                    router.RegisterRoute(messageType, address);
                });
            }
        }
Пример #3
0
 /// <summary>
 ///     Lists all message type for which we have handlers
 /// </summary>
 public IEnumerable <Type> GetMessageTypes()
 {
     return(from handlers in handlerList.Values
            from typeHandled in handlers
            where MessageConventionExtensions.IsMessageType(typeHandled)
            select typeHandled);
 }
Пример #4
0
        static bool IsEncryptedMember(MemberInfo arg)
        {
            var propertyInfo = arg as PropertyInfo;

            if (propertyInfo != null)
            {
                if (propertyInfo.GetIndexParameters().Length > 0)
                {
                    if (MessageConventionExtensions.IsEncryptedProperty(propertyInfo))
                    {
                        throw new Exception("Cannot encrypt or decrypt indexed properties that return a WireEncryptedString.");
                    }

                    return(false);
                }

                return(MessageConventionExtensions.IsEncryptedProperty(propertyInfo));
            }

            var fieldInfo = arg as FieldInfo;

            if (fieldInfo != null)
            {
                return(fieldInfo.FieldType == typeof(WireEncryptedString));
            }

            return(false);
        }
Пример #5
0
 public static void AssertIsValidForReply(Type messageType)
 {
     if (MessageConventionExtensions.IsCommandType(messageType) || MessageConventionExtensions.IsEventType(messageType))
     {
         throw new InvalidOperationException("Reply is neither supported for Commands nor Events. Commands should be sent to their logical owner using bus.Send and bus. Events should be Published with bus.Publish.");
     }
 }
Пример #6
0
 /// <summary>
 /// Enforce messaging rules. Make sure, the message can be used by Bus.Reply.
 /// </summary>
 /// <param name="messages">Collection of messages to enforce messaging rules on.</param>
 public static void AssertIsValidForReply(IEnumerable <object> messages)
 {
     if (messages.Any(m => MessageConventionExtensions.IsCommand(m) || MessageConventionExtensions.IsEvent(m)))
     {
         throw new InvalidOperationException(
                   "Reply is neither supported for Commands nor Events. Commands should be sent to their logical owner using bus.Send and bus. Events should be Published with bus.Publish.");
     }
 }
Пример #7
0
        static TimeSpan TimeToBeReceived(object message)
        {
            if (GetDataBusProperties(message).Count == 0)
            {
                return(TimeSpan.MaxValue);
            }

            return(MessageConventionExtensions.TimeToBeReceivedAction(message.GetType()));
        }
Пример #8
0
 /// <summary>
 ///     If the type is a message handler, returns all the message types that it handles
 /// </summary>
 static IEnumerable <Type> GetMessageTypesIfIsMessageHandler(Type type)
 {
     return(from t in type.GetInterfaces()
            where t.IsGenericType
            let potentialMessageType = t.GetGenericArguments()[0]
                                       where
                                       MessageConventionExtensions.IsMessageType(potentialMessageType) ||
                                       typeof(IHandleMessages <>).MakeGenericType(potentialMessageType).IsAssignableFrom(t)
                                       select potentialMessageType);
 }
 public IEnumerable <Type> GetEventsToSubscribe()
 {
     return(HandlerRegistry.GetMessageTypes()
            //get all potential messages
            .Where(t => !MessageConventionExtensions.IsCommandType(t) && (SubscribePlainMessages || MessageConventionExtensions.IsEventType(t)))
            //get messages that has routing if required
            .Where(t => DoNotRequireExplicitRouting || MessageRouter.GetDestinationFor(t).Any())
            //get messages with other handlers than sagas if needed
            .Where(t => !DoNotAutoSubscribeSagas || HandlerRegistry.GetHandlerTypes(t).Any(handler => !typeof(ISaga).IsAssignableFrom(handler)))
            .ToList());
 }
        public void Run()
        {
            if (Mapper == null)
            {
                return;
            }

            var messageTypes = Configure.TypesToScan.Where(t => MessageConventionExtensions.IsMessageType(t)).ToList();

            Mapper.Initialize(messageTypes);
            Serializer.Initialize(messageTypes);
        }
Пример #11
0
        /// <summary>
        /// Enforce messaging rules. Make sure, the message can be used by pubsub bus methods (<see cref="IBus.Subscribe(System.Type)"/>, <see cref="IBus.Unsubscribe"/> and <see cref="IBus.Publish{T}(T[])"/>)..
        /// </summary>
        public static void AssertIsValidForPubSub(Type messageType)
        {
            if (MessageConventionExtensions.IsCommandType(messageType))
            {
                throw new InvalidOperationException("Pub/Sub is not supported for Commands. They should be be sent direct to their logical owner.");
            }

            if (!MessageConventionExtensions.IsEventType(messageType))
            {
                Log.Info("You are using a basic message to do pub/sub, consider implementing the more specific ICommand and IEvent interfaces to help NServiceBus to enforce messaging best practices for you.");
            }
        }
Пример #12
0
        static void ConfigureFinder(Type t)
        {
            foreach (Type interfaceType in t.GetInterfaces())
            {
                Type[] args = interfaceType.GetGenericArguments();
                if (args.Length != 2)
                {
                    continue;
                }

                Type sagaEntityType = null;
                Type messageType    = null;
                foreach (Type typ in args)
                {
                    if (typeof(IContainSagaData).IsAssignableFrom(typ))
                    {
                        sagaEntityType = typ;
                    }

                    if (MessageConventionExtensions.IsMessageType(typ) || typ == typeof(object))
                    {
                        messageType = typ;
                    }
                }

                if (sagaEntityType == null || messageType == null)
                {
                    continue;
                }

                Type finderType = typeof(IFindSagas <> .Using <>).MakeGenericType(sagaEntityType, messageType);
                if (!finderType.IsAssignableFrom(t))
                {
                    continue;
                }

                FinderTypeToSagaEntityTypeLookup[t] = sagaEntityType;

                MethodInfo method = t.GetMethod("FindBy", new[] { messageType });

                IDictionary <Type, MethodInfo> methods;
                FinderTypeToMessageToMethodInfoLookup.TryGetValue(t, out methods);

                if (methods == null)
                {
                    methods = new Dictionary <Type, MethodInfo>();
                    FinderTypeToMessageToMethodInfoLookup[t] = methods;
                }

                methods[messageType] = method;
            }
        }
        void RegisterMessageOwnersAndBusAddress(IEnumerable <Type> knownMessages)
        {
            var unicastConfig = Configure.GetConfigSection <UnicastBusConfig>();
            var router        = new StaticMessageRouter(knownMessages);
            var key           = typeof(DefaultAutoSubscriptionStrategy).FullName + ".SubscribePlainMessages";

            if (SettingsHolder.HasSetting(key))
            {
                router.SubscribeToPlainMessages = SettingsHolder.Get <bool>(key);
            }

            Configure.Instance.Configurer.RegisterSingleton <StaticMessageRouter>(router);

            if (unicastConfig == null)
            {
                return;
            }

            if (!string.IsNullOrWhiteSpace(unicastConfig.ForwardReceivedMessagesTo))
            {
                var forwardAddress = Address.Parse(unicastConfig.ForwardReceivedMessagesTo);
                Configure.Instance.Configurer.ConfigureProperty <UnicastBus>(b => b.ForwardReceivedMessagesTo,
                                                                             forwardAddress);
                Configure.Instance.Configurer.ConfigureProperty <ForwardBehavior>(b => b.ForwardReceivedMessagesTo, forwardAddress);
            }
            Configure.Instance.Configurer.ConfigureProperty <UnicastBus>(b => b.TimeToBeReceivedOnForwardedMessages,
                                                                         unicastConfig.TimeToBeReceivedOnForwardedMessages);
            Configure.Instance.Configurer.ConfigureProperty <ForwardBehavior>(b => b.TimeToBeReceivedOnForwardedMessages, unicastConfig.TimeToBeReceivedOnForwardedMessages);

            var messageEndpointMappings = unicastConfig.MessageEndpointMappings.Cast <MessageEndpointMapping>()
                                          .OrderByDescending(m => m)
                                          .ToList();

            foreach (var mapping in messageEndpointMappings)
            {
                mapping.Configure((messageType, address) =>
                {
                    if (!(MessageConventionExtensions.IsMessageType(messageType) || MessageConventionExtensions.IsEventType(messageType) || MessageConventionExtensions.IsCommandType(messageType)))
                    {
                        return;
                    }

                    if (MessageConventionExtensions.IsEventType(messageType))
                    {
                        router.RegisterEventRoute(messageType, address);
                        return;
                    }

                    router.RegisterMessageRoute(messageType, address);
                });
            }
        }
Пример #14
0
 /// <summary>
 /// Lists all message type for which we have handlers
 /// </summary>
 /// <returns></returns>
 public IEnumerable <Type> GetMessageTypes()
 {
     foreach (var handlerType in handlerList.Keys)
     {
         foreach (var typeHandled in handlerList[handlerType])
         {
             if (MessageConventionExtensions.IsMessageType(typeHandled))
             {
                 yield return(typeHandled);
             }
         }
     }
 }
Пример #15
0
        static List <PropertyInfo> GetDataBusProperties(object message)
        {
            var messageType = message.GetType();

            if (!cache.ContainsKey(messageType))
            {
                cache[messageType] = messageType.GetProperties()
                                     .Where(property => MessageConventionExtensions.IsDataBusProperty(property))
                                     .ToList();
            }

            return(cache[messageType]);
        }
Пример #16
0
        public void Start()
        {
            if (!Feature.IsEnabled <AutoSubscribe>())
            {
                return;
            }


            foreach (var eventType in AutoSubscriptionStrategy.GetEventsToSubscribe()
                     .Where(t => !MessageConventionExtensions.IsInSystemConventionList(t))) //never auto-subscribe system messages
            {
                Bus.Subscribe(eventType);

                Logger.DebugFormat("Auto subscribed to event {0}", eventType);
            }
        }
Пример #17
0
            public void Should_cache_the_message_convention()
            {
                var timesCalled = 0;

                MessageConventionExtensions.IsCommandTypeAction = t =>
                {
                    timesCalled++;
                    return(false);
                };

                MessageConventionExtensions.IsCommand(this);
                Assert.AreEqual(1, timesCalled);

                MessageConventionExtensions.IsCommand(this);
                Assert.AreEqual(1, timesCalled);
            }
Пример #18
0
        public void RegisterMessageType(Type messageType)
        {
            var metadata = new MessageMetadata
            {
                MessageType      = messageType,
                Recoverable      = !DefaultToNonPersistentMessages,
                TimeToBeReceived = MessageConventionExtensions.TimeToBeReceivedAction(messageType)
            };

            if (MessageConventionExtensions.IsExpressMessageType(messageType))
            {
                metadata.Recoverable = false;
            }

            messages[messageType] = metadata;
        }
Пример #19
0
 static IEnumerable <Type> GetMessagesCorrespondingToFilterOnSaga(Type sagaType, Type filter)
 {
     foreach (Type interfaceType in sagaType.GetInterfaces())
     {
         Type[] types = interfaceType.GetGenericArguments();
         foreach (Type arg in types)
         {
             if (MessageConventionExtensions.IsMessageType(arg))
             {
                 if (filter.MakeGenericType(arg) == interfaceType)
                 {
                     yield return(arg);
                 }
             }
         }
     }
 }
Пример #20
0
        /// <summary>
        /// If the type is a message handler, returns all the message types that it handles
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        static IEnumerable <Type> GetMessageTypesIfIsMessageHandler(Type type)
        {
            foreach (var t in type.GetInterfaces().Where(t => t.IsGenericType))
            {
                var potentialMessageType = t.GetGenericArguments().SingleOrDefault();

                if (potentialMessageType == null)
                {
                    continue;
                }


                if (MessageConventionExtensions.IsMessageType(potentialMessageType) ||
                    typeof(IHandleMessages <>).MakeGenericType(potentialMessageType).IsAssignableFrom(t))
                {
                    yield return(potentialMessageType);
                }
            }
        }
Пример #21
0
        /// <summary>
        /// Specify a test for a message handler specifying a callback to create
        /// the handler and getting an instance of the bus passed in.
        /// Useful for handlers based on constructor injection.
        /// </summary>
        public static Handler <T> Handler <T>(Func <IBus, T> handlerCreationCallback)
        {
            bus = new StubBus(messageCreator);
            ExtensionMethods.Bus = bus;

            var handler = handlerCreationCallback.Invoke(bus);

            var isHandler = (from i in handler.GetType().GetInterfaces()
                             let args = i.GetGenericArguments()
                                        where args.Length == 1
                                        where MessageConventionExtensions.IsMessageType(args[0])
                                        where typeof(IHandleMessages <>).MakeGenericType(args[0]).IsAssignableFrom(i)
                                        select i).Any();

            if (!isHandler)
            {
                throw new ArgumentException("The handler object created does not implement IHandleMessages<T>.", "handlerCreationCallback");
            }

            var messageTypes = Configure.TypesToScan.Where(MessageConventionExtensions.IsMessageType).ToList();

            return(new Handler <T>(handler, bus, messageCreator, messageTypes));
        }
Пример #22
0
        static IEnumerable <Type> GetMessagesCorrespondingToFilterOnSaga(Type sagaType, Type filter)
        {
            foreach (var interfaceType in sagaType.GetInterfaces())
            {
                foreach (var argument in interfaceType.GetGenericArguments())
                {
                    var genericType    = filter.MakeGenericType(argument);
                    var isOfFilterType = genericType == interfaceType;
                    if (!isOfFilterType)
                    {
                        continue;
                    }
                    if (MessageConventionExtensions.IsMessageType(argument))
                    {
                        yield return(argument);

                        continue;
                    }
                    var message = string.Format("The saga '{0}' implements '{1}' but the message type '{2}' is not classified as a message. You should either use 'Unobtrusive Mode Messages' or the message should implement either 'IMessage', 'IEvent' or 'ICommand'.", sagaType.FullName, genericType.Name, argument.FullName);
                    throw new Exception(message);
                }
            }
        }
Пример #23
0
        private static bool IsWcfService(Type t)
        {
            var args = t.GetGenericArguments();

            if (args.Length == 2)
            {
                if (MessageConventionExtensions.IsMessageType(args[0]))
                {
                    var wcfType = typeof(WcfService <,>).MakeGenericType(args);
                    if (wcfType.IsAssignableFrom(t))
                    {
                        return(true);
                    }
                }
            }

            if (t.BaseType != null)
            {
                return(IsWcfService(t.BaseType) && !t.IsAbstract);
            }

            return(false);
        }
Пример #24
0
        public void RegisterMessageType(Type messageType)
        {
            var metadata = new MessageMetadata
            {
                MessageType      = messageType,
                Recoverable      = !DefaultToNonPersistentMessages,
                TimeToBeReceived = MessageConventionExtensions.TimeToBeReceivedAction(messageType)
            };

            if (MessageConventionExtensions.IsExpressMessageType(messageType))
            {
                metadata.Recoverable = false;
            }

            //get the parent types
            var parentMessages = GetParentTypes(messageType)
                                 .Where(MessageConventionExtensions.IsMessageType)
                                 .OrderByDescending(PlaceInMessageHierarchy)
                                 .ToList();

            metadata.MessageHierarchy = new[] { messageType }.Concat(parentMessages);

            messages[messageType] = metadata;
        }
Пример #25
0
        List <string> GetBaseTypes(object[] messages)
        {
            var result = new List <string>();

            foreach (var m in messages)
            {
                var t = mapper.GetMappedTypeFor(m.GetType());

                var baseType = t.BaseType;
                while (baseType != typeof(object) && baseType != null)
                {
                    if (MessageConventionExtensions.IsMessageType(baseType))
                    {
                        if (!result.Contains(baseType.FullName))
                        {
                            result.Add(baseType.FullName);
                        }
                    }

                    baseType = baseType.BaseType;
                }

                foreach (var i in t.GetInterfaces())
                {
                    if (MessageConventionExtensions.IsMessageType(i))
                    {
                        if (!result.Contains(i.FullName))
                        {
                            result.Add(i.FullName);
                        }
                    }
                }
            }

            return(result);
        }
Пример #26
0
        public void Should_use_TimeToBeReceived_from_bottom_of_tree()
        {
            var timeToBeReceivedAction = MessageConventionExtensions.TimeToBeReceivedAction(typeof(InheritedClassWithAttribute));

            Assert.AreEqual(TimeSpan.FromSeconds(2), timeToBeReceivedAction);
        }
Пример #27
0
 /// <summary>
 /// Add system messages convention
 /// </summary>
 public static Configure AddSystemMessagesAs(this Configure config, Func <Type, bool> definesMessageType)
 {
     MessageConventionExtensions.AddSystemMessagesConventions(definesMessageType);
     return(config);
 }
Пример #28
0
 /// <summary>
 /// Invoked before configuration starts.
 /// </summary>
 public void Init()
 {
     MessageConventionExtensions.AddSystemMessagesConventions(t => typeof(SendEmail) == t);
 }
 public void Init()
 {
     MessageConventionExtensions.AddSystemMessagesConventions(t => t.Namespace != null &&
                                                              t.Namespace.StartsWith("ServiceControl.Plugin.") &&
                                                              t.Namespace.EndsWith(".Messages"));
 }
 public void Init()
 {
     MessageConventionExtensions.AddSystemMessagesConventions(t => typeof(Messages.ScheduledTask).IsAssignableFrom(t));
 }