public RegisteryItem(Type messageType, object handler, IMessageHandlerActionExecutor handlerMethodSelector)
 {
     HandlerType           = handler.GetType();
     MessageType           = messageType;
     Handler               = new WeakReference <object>(handler, false);
     HandlerMethodSelector = handlerMethodSelector;
 }
        private void Subscribe(IMessageHandler handler, Type messageType, IMessageHandlerActionExecutor methodSelector)
        {
            var messageHandlerType = handler.GetType();
            var rules = GetRule(messageHandlerType, messageType);

            if (null != rules && rules.Count > 0)
            {
                foreach (var rule in rules)
                {
                    var items = RuleSubscriptions.ItemsByRule(rule);
                    var item  = items.FirstOrDefault(it => it.handler == handler);
                    if (null == item)
                    {
                        IObservable <IMessage> observable;

                        if (null != rule.Transformer)
                        {
                            observable =
                                Messages.Where(
                                    message =>
                                    rule.IncludeDrivedMessageTypes
                                            ? rule.Transformer.InputType.IsInstanceOfType(message)
                                            : message.GetType() == rule.Transformer.InputType);

                            if (null != rule.PreCondition)
                            {
                                observable = observable.Where(message => Scripts.CQRS.Validators.ValidationResult.Accepted == rule.PreCondition.Validate(handler, message));
                            }
                            observable = observable.Select(message => Convert.ChangeType(rule.Transformer.Transform(message), rule.Transformer.OutpuType) as IMessage);
                        }
                        else
                        {
                            observable = Messages.Where(message => rule.IncludeDrivedMessageTypes ? messageType.IsInstanceOfType(message) : messageType == message.GetType());
                        }

                        if (null != rule.PostCondition)
                        {
                            observable = observable.Where(message => Scripts.CQRS.Validators.ValidationResult.Accepted == rule.PostCondition.Validate(handler, message));
                        }

                        var subscription = observable.Subscribe(message => methodSelector.Execute(message));

                        RuleSubscriptions.Add(new SubscriptionRegisteryItem()
                        {
                            Route              = rule,
                            handler            = handler,
                            methodInfo         = methodSelector,
                            MessagehandlerType = messageHandlerType,
                            MessageType        = messageType,
                            Subscription       = subscription
                        });
                    }
                    else
                    {
                        //Debug.LogWarning("Duplicate Subscription.");
                    }
                }
            }
            else
            {
                UnityEngine.Debug.LogWarning($"Message Rule for {messageHandlerType.Name}<{messageType}> Not Found.");

                var registeryItem = new RegisteryItem(messageType, handler, methodSelector);
                _subscribedHandlerWithoutRule.Add(registeryItem);
            }
        }
 public void Subscribe <TMessageHandler, TMessage>(TMessageHandler handler, IMessageHandlerActionExecutor methodSelector)
     where TMessage : class, IMessage
     where TMessageHandler : class, IMessageHandler <TMessage>
 {
     Subscribe(handler, typeof(TMessage), methodSelector);
 }