예제 #1
0
        public void AddSynchronizedHandler <TRequest, TResponse>(Func <TRequest, TResponse> callback)
        {
            Validate();

            if (callback == null)
            {
                throw new ArgumentNullException(nameof(callback));
            }

            if (callback.Target == null)
            {
                throw new ArgumentException("Can't use static methods in callbacks.", nameof(callback));
            }

            SynchronizedHandlerKey key = new SynchronizedHandlerKey(typeof(TRequest), typeof(TResponse));

            SynchronizedHandler synchronizedHandler = new SynchronizedHandler(callback);


            lock (_synchronizedHandlers)
            {
                if (_synchronizedHandlers.ContainsKey(key))
                {
                    throw new ArgumentException($"A SynchronizedHandler already exists for request type {typeof(TRequest)} and response type {typeof(TResponse)}", nameof(callback));
                }

                _synchronizedHandlers[key] = synchronizedHandler;
            }
        }
예제 #2
0
        public void Register(object handler)
        {
            Validate();

            if (handler == null)
            {
                throw new ArgumentNullException(nameof(handler));
            }

            // Look for, and save, any IEventHandler implementations
            IEnumerable <Type> eventInterfaces = handler.GetType().GetInterfaces()
                                                 .Where(x => typeof(IEventHandler).IsAssignableFrom(x) && x.IsGenericType);

            lock (_eventHandlers)
            {
                foreach (var @interface in eventInterfaces)
                {
                    Type       type   = @interface.GetGenericArguments()[0];
                    MethodInfo method = @interface.GetMethod("HandleEvent", new[] { type });

                    if (method != null)
                    {
                        Delegate @delegate = Delegate.CreateDelegate(typeof(Action <>).MakeGenericType(type), handler, method);

                        EventHandler eventHandler = new EventHandler(@delegate);

                        if (!_eventHandlers.ContainsKey(type))
                        {
                            _eventHandlers[type] = new List <EventHandler>();
                        }

                        if (!_eventHandlers[type].Contains(eventHandler))
                        {
                            _eventHandlers[type].Add(eventHandler);
                        }
                    }
                }
            }

            // Look for, and save, any ISynchronizedHandler implementations
            IEnumerable <Type> synchronizedInterfaces = handler.GetType().GetInterfaces()
                                                        .Where(x => typeof(ISynchronizedHandler).IsAssignableFrom(x) && x.IsGenericType);

            lock (_synchronizedHandlers)
            {
                foreach (var @interface in synchronizedInterfaces)
                {
                    Type requestType  = @interface.GetGenericArguments()[0];
                    Type responseType = @interface.GetGenericArguments()[1];

                    MethodInfo method = @interface.GetMethod("HandleSynchronized", new[] { requestType });

                    if (method != null && method.ReturnType.IsAssignableFrom(responseType))
                    {
                        Delegate @delegate = Delegate.CreateDelegate(typeof(Func <,>).MakeGenericType(requestType, responseType), handler, method);

                        SynchronizedHandlerKey key = new SynchronizedHandlerKey(requestType, responseType);

                        SynchronizedHandler synchronizedHandler = new SynchronizedHandler(@delegate);

                        lock (_synchronizedHandlers)
                        {
                            if (_synchronizedHandlers.ContainsKey(key))
                            {
                                throw new ArgumentException($"A SynchronizedHandler already exists for request type {requestType} and response type {responseType}", nameof(@delegate));
                            }

                            _synchronizedHandlers[key] = synchronizedHandler;
                        }
                    }
                }
            }
        }
예제 #3
0
        private void Transport_MessageReceived(object sender, Events.MessageReceivedEventArgs e)
        {
            try
            {
                MessageWrapper wrapper = e.Message;

                if (wrapper.MessageType == MessageType.Event)
                {
                    lock (_eventHandlers)
                    {
                        EventHandler[] handlers = _eventHandlers.Where(h => h.Key.IsAssignableFrom(wrapper.DataType)).SelectMany(h => h.Value).ToArray();
                        foreach (EventHandler handler in handlers)
                        {
                            try
                            {
                                new Thread(() =>
                                {
                                    try
                                    {
                                        if (!handler.Invoke(wrapper.Data))
                                        {
                                            _eventHandlers[wrapper.DataType].Remove(handler);
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        PublishUnhandledException(ex);
                                    }
                                }).Start();
                            }
                            catch (Exception ex)
                            {
                                PublishUnhandledException(ex);
                            }
                        }
                    }
                }
                else if (wrapper.MessageType == MessageType.SynchronizedRequest)
                {
                    SynchronizedHandler handler = null;

                    lock (_synchronizedHandlers)
                    {
                        SynchronizedHandlerKey key = new SynchronizedHandlerKey(wrapper.DataType, wrapper.ResponseType);

                        if (_synchronizedHandlers.ContainsKey(key))
                        {
                            handler = _synchronizedHandlers[key];

                            if (!handler.IsAlive)
                            {
                                _synchronizedHandlers.Remove(key);
                            }
                        }
                    }

                    if (handler != null && handler.IsAlive)
                    {
                        new Thread(() =>
                        {
                            try
                            {
                                object result = handler.Invoke(wrapper.Data);

                                MessageWrapper replyWrapper = new MessageWrapper
                                {
                                    MessageType   = MessageType.SynchronizedResponse,
                                    Data          = result,
                                    DataType      = wrapper.DataType,
                                    ResponseType  = wrapper.ResponseType,
                                    CorrelationId = wrapper.CorrelationId
                                };

                                _transport.Publish(replyWrapper);
                            }
                            catch (Exception ex)
                            {
                                PublishUnhandledException(ex);
                            }
                        }).Start();
                    }
                }
                else if (wrapper.MessageType == MessageType.SynchronizedResponse)
                {
                    lock (_synchronizationPackages)
                    {
                        if (_synchronizationPackages.ContainsKey(wrapper.CorrelationId))
                        {
                            SynchronizedDataPackage pkg = _synchronizationPackages[wrapper.CorrelationId];

                            pkg.Data = wrapper.Data;
                            pkg.ResetEvent.Set();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                PublishUnhandledException(ex);
            }
        }