Exemplo n.º 1
0
            public void Raise(string eventName, params string[] parameters)
            {
                EventInfo eventInfo;

                if (!Events.TryGetValue(eventName, out eventInfo))
                {
                    eventInfo = InstanceType.GetEvent(eventName);
                    if (eventInfo == null && InstanceType.IsInterface)
                    {
                        // search event in parent interfaces
                        foreach (var parentInterface in InstanceType.GetInterfaces())
                        {
                            eventInfo = parentInterface.GetEvent(eventName);
                            if (eventInfo != null)
                            {
                                break;
                            }
                        }
                    }
                    if (eventInfo == null)
                    {
                        throw new Exception(string.Format("Event not found. Type: {0}, EventName: {1}", InstanceType.FullName, eventName));
                    }
                    Events[eventName] = eventInfo;
                }
                Type      eventArgsType = GetEventArgsType(eventInfo);
                EventArgs eventArgsValue;

                try
                {
                    if (parameters.Length > 0)
                    {
                        eventArgsValue = JsonConvert.DeserializeObject(parameters[0], eventArgsType) as EventArgs;
                    }
                    else
                    {
                        eventArgsValue = EventArgs.Empty;
                    }
                }
                catch (Exception ex)
                {
                    RoqueTrace.Source.Trace(TraceEventType.Error, "Error deserializing event args: {0}. Event: {1}, Expected Type: {2}",
                                            ex.Message, eventInfo.Name, eventArgsType.FullName, ex);
                    throw;
                }

                MethodInfo handlerMethod = null;

                try
                {
                    if (Instance is EventProxyGenerator.IEventProxy)
                    {
                        var handlers = ((EventProxyGenerator.IEventProxy)Instance).GetHandlersForEvent(eventInfo.Name);
                        if (handlers.Length > 0)
                        {
                            foreach (var handler in handlers)
                            {
                                handlerMethod = handler.Method;
                                handlerMethod.Invoke(handler.Target, new object[] { Instance, eventArgsValue });
                            }
                        }
                        else
                        {
                            RoqueTrace.Source.Trace(TraceEventType.Warning, "No suscribers found for event: {0}", eventInfo.Name);
                        }
                    }
                    else
                    {
                        var privateDelegatesField = Instance.GetType().GetField(eventInfo.Name, BindingFlags.Instance | BindingFlags.NonPublic);
                        var eventDelegate         = (MulticastDelegate)privateDelegatesField.GetValue(Instance);
                        if (eventDelegate != null)
                        {
                            foreach (var handler in eventDelegate.GetInvocationList())
                            {
                                handler.Method.Invoke(handler.Target, new object[] { Instance, eventArgsValue });
                            }
                        }
                    }
                }
                catch (TargetInvocationException ex)
                {
                    var jobException = ex.InnerException;
                    RoqueTrace.Source.Trace(TraceEventType.Error, "Error invoking event handler: {0}\n\n{1}", jobException.Message, jobException);
                    var jobExceptionType = jobException.GetType();
                    if (jobException is ShouldRetryException)
                    {
                        throw jobException;
                    }
                    var retryOn = handlerMethod.GetCustomAttributes(typeof(RetryOnAttribute), true)
                                  .OfType <RetryOnAttribute>()
                                  .FirstOrDefault(attr => attr.ExceptionType.IsAssignableFrom(jobExceptionType));
                    if (retryOn == null)
                    {
                        retryOn = handlerMethod.DeclaringType.GetCustomAttributes(typeof(RetryOnAttribute), true)
                                  .OfType <RetryOnAttribute>()
                                  .FirstOrDefault(attr => attr.ExceptionType.IsAssignableFrom(jobExceptionType));
                    }
                    if (retryOn != null && !(retryOn is DontRetryOnAttribute))
                    {
                        throw retryOn.CreateException(jobException);
                    }
                    throw;
                }
            }