using System.Collections.Generic; using System.Reflection; using Caliburn.Events.Brokering; using Spring.Objects.Factory.Config; namespace Caliburn.Spring { public class EventRegistrationObjectPostProcessor : IObjectPostProcessor { private readonly Dictionary> _publishers = new Dictionary>(); private readonly Dictionary> _subscribers = new Dictionary>(); private static IEventBroker _eventBroker { get { return DI.Resolve(); } } #region IObjectPostProcessor Members public object PostProcessBeforeInitialization(object instance, string name) { return instance; } public object PostProcessAfterInitialization(object instance, string objectName) { return WireEvents(instance, objectName); } #endregion private object WireEvents(object instance, string name) { HandleSubscribers(instance, name); HandlePublishers(instance, name); return instance; } private void HandleSubscribers(object instance, string name) { IDictionary subscribedMethods = GetSubscribedMethods(instance, name); foreach(KeyValuePair subscribedMethod in subscribedMethods) { _eventBroker.Subscribe( subscribedMethod.Key.EventNodeName, new Subscription(instance, subscribedMethod.Value, subscribedMethod.Key.IsAsync) ); } } private IDictionary GetSubscribedMethods(object instance, string name) { IDictionary subscribedMethods; if(!_subscribers.TryGetValue(name, out subscribedMethods)) { subscribedMethods = _eventBroker.GetSubscribedMethods(instance.GetType()); _subscribers[name] = subscribedMethods; } return subscribedMethods; } private void HandlePublishers(object instance, string name) { IDictionary publishedEvents = GetPublishedEvents(instance, name); foreach(KeyValuePair publishedEvent in publishedEvents) { _eventBroker.Publish( instance, publishedEvent.Value, publishedEvent.Key.BuildPublication() ); } } private IDictionary GetPublishedEvents(object instance, string name) { IDictionary publishedEvents; if(!_publishers.TryGetValue(name, out publishedEvents)) { publishedEvents = _eventBroker.GetPublishedEvents(instance.GetType()); _publishers[name] = publishedEvents; } return publishedEvents; } } }