| 134 | 1 using System; | 
|  | 2 using System.Collections.Generic; | 
| 152 | 3 using Implab.Components; | 
| 134 | 4 | 
|  | 5 namespace Implab.Diagnostics { | 
|  | 6     public abstract class ListenerBase : ServiceLocator, ILogWriter<object>, ILogWriter<TraceEvent> { | 
|  | 7 | 
|  | 8         readonly Dictionary<object, Action> m_subscriptions = new Dictionary<object, Action>(); | 
|  | 9 | 
|  | 10         protected ListenerBase() { | 
|  | 11             Register(this); | 
|  | 12         } | 
|  | 13 | 
|  | 14         public void Subscribe(Type eventType) { | 
|  | 15             if (eventType == null) | 
|  | 16                 throw new ArgumentNullException("eventType"); | 
|  | 17             GetType().GetMethod("Subscribe", new Type[0]).MakeGenericMethod(eventType).Invoke(this, null); | 
|  | 18         } | 
|  | 19 | 
|  | 20         public void Subscribe<TEvent>() { | 
|  | 21             Subscribe<TEvent>(LogChannel<TEvent>.Default); | 
|  | 22         } | 
|  | 23 | 
|  | 24         public void Subscribe<TEvent>(LogChannel<TEvent> channel) { | 
|  | 25             if (channel == null) | 
|  | 26                 throw new ArgumentNullException("channel"); | 
|  | 27 | 
|  | 28             lock (m_subscriptions) { | 
|  | 29                 AssertNotDisposed(); | 
|  | 30                 if (m_subscriptions.ContainsKey(channel)) | 
|  | 31                     return; | 
|  | 32 | 
|  | 33                 var writer = GetService<ILogWriter<TEvent>>(); | 
|  | 34 | 
|  | 35                 EventHandler<LogEventArgs<TEvent>> handler = (sender, args) => writer.Write(args,args.Value); | 
|  | 36 | 
|  | 37                 channel.Events += handler; | 
|  | 38 | 
|  | 39                 Action unsubscribe = () => { | 
|  | 40                     channel.Events -= handler; | 
|  | 41                 }; | 
|  | 42 | 
|  | 43                 m_subscriptions.Add(channel, unsubscribe); | 
|  | 44             } | 
|  | 45         } | 
|  | 46 | 
|  | 47         public void Unsubscribe<TEvent>(LogChannel<TEvent> channel) { | 
|  | 48             if (channel == null) | 
|  | 49                 throw new ArgumentNullException("channel"); | 
|  | 50 | 
|  | 51             lock (m_subscriptions) { | 
|  | 52                 Action subscription; | 
|  | 53                 if (m_subscriptions.TryGetValue(channel, out subscription)) { | 
|  | 54                     subscription(); | 
|  | 55                     m_subscriptions.Remove(channel); | 
|  | 56                 } | 
|  | 57             } | 
|  | 58         } | 
|  | 59 | 
|  | 60         public void UnsubscribeAll() { | 
|  | 61             lock (m_subscriptions) { | 
| 194 | 62                 foreach (var remove in m_subscriptions.Values) | 
|  | 63                     remove(); | 
| 134 | 64                 m_subscriptions.Clear(); | 
|  | 65             } | 
|  | 66         } | 
|  | 67 | 
|  | 68         #region ILogWriter implementation | 
|  | 69         public abstract void Write(LogEventArgs args, object entry); | 
|  | 70         #endregion | 
|  | 71 | 
|  | 72         #region ILogWriter implementation | 
|  | 73         public virtual void Write(LogEventArgs args, TraceEvent entry) { | 
|  | 74             Write(args, (object)entry); | 
|  | 75         } | 
|  | 76         #endregion | 
|  | 77 | 
|  | 78 | 
|  | 79         protected override void Dispose(bool disposing) { | 
|  | 80             base.Dispose(disposing); | 
|  | 81             if (disposing) { | 
|  | 82                 UnsubscribeAll(); | 
|  | 83             } | 
|  | 84         } | 
|  | 85     } | 
|  | 86 } |