public void ObserveEvents() { var methodsWithAttributes = from methodInfo in _eventProcessor.GetType().GetMethodsRecursive(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) let observeEventAttributes = methodInfo.GetCustomAttributes <ObserveEventAttribute>(true).ToArray() where observeEventAttributes.Length > 0 select new { methodInfo, observeEventAttributes }; foreach (var methodWithAttributes in methodsWithAttributes) { ObserveEventAttribute[] observeEventAttributes = methodWithAttributes.observeEventAttributes; MethodInfo method = methodWithAttributes.methodInfo; if (observeEventAttributes.Length == 1) { ObserveEventAttribute observeEventAttribute = observeEventAttributes[0]; EnsureObserveEventSignatureCorrect(method, observeEventAttribute.EventType); var eventObservable = CreateEventObservable(observeEventAttribute); var observeDelegate = CreateEventObserverDelegate(method, observeEventAttribute.EventType); ObserveEvent(eventObservable, observeDelegate); } else { var baseEventType = GetBaseEventType(method, observeEventAttributes); EnsureObserveEventSignatureCorrect(method, baseEventType); var eventObservable = CreateEventObservable(baseEventType, observeEventAttributes); var observeDelegate = CreateEventObserverDelegate(method, baseEventType); ObserveEvent(eventObservable, observeDelegate); } } }
// gets a merged IEventObservable<TEvent, TContext, TModel> for all events in the given attributes, the merged streams TEvent is of baseEventType private object CreateEventObservable(Type baseEventType, ObserveEventAttribute[] observeEventAttributes) { var eventObservableType = typeof(IEventObservable <, ,>).MakeGenericType(new Type[] { baseEventType, typeof(IEventContext), typeof(TModel) }); var eventObservables = (IList)typeof(List <>) .MakeGenericType(eventObservableType) .GetConstructor(new Type[] {}) .Invoke(null); for (int i = 0; i < observeEventAttributes.Length; i++) { ObserveEventAttribute observeEventAttribute = observeEventAttributes[i]; dynamic eventObservable = CreateEventObservable(observeEventAttribute); eventObservables.Add(eventObservable); } MethodInfo closedEventObservableMergeMethod = ObservableMergeMethodInfo.MakeGenericMethod(new Type[] { baseEventType, typeof(IEventContext), typeof(TModel) }); return(closedEventObservableMergeMethod.Invoke(null, new object[] { eventObservables })); }
// gets an IEventObservable<TEvent, TContext, TModel> for the details in the given attribute private object CreateEventObservable(ObserveEventAttribute observeEventAttribute) { var getEventObservableMethod = GetEventObservableMethodInfo.MakeGenericMethod(observeEventAttribute.EventType); return(getEventObservableMethod.Invoke(_router, new object[] { observeEventAttribute.Stage })); }