using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using ClientList = System.Collections.Generic.List; namespace LiveLogger4Log4Net { /// /// Helps to keep track of registration of the clients. /// public class RegistrationList { /// /// This is the list of the clients that wants to listen to all channels. /// private ClientList clientsThatListenToAllLoggers = new ClientList(); /// /// some clients can ask only for some logger, so I keep a map that for each /// logger name stores all clients in a list. /// private Dictionary clients = new Dictionary(); /// /// Add a client that will listen to all loggers. /// /// public void Add(IL4NClient client) { clientsThatListenToAllLoggers.Add(client); } /// /// Add a client that will listen only to specific loggers /// /// /// public void Add(IL4NClient client, IEnumerable loggerList) { foreach (String loggerName in loggerList) { if (!clients.ContainsKey(loggerName)) { clients.Add(loggerName, new ClientList()); } clients[loggerName].Add(client); } } /// /// Add a client that will listen only to specific loggers /// /// /// public void Add(IL4NClient client, params String[] loggerList) { Add(client, (IEnumerable)loggerList); } #region Enumerators /// /// Enumerate through all listening channels /// /// public IEnumerable GetEnumerator(String loggerName) { foreach (IL4NClient client in clientsThatListenToAllLoggers.Union( clients.ContainsKey(loggerName) ? clients[loggerName] : Enumerable.Empty())) yield return client; } #endregion /// /// invoke the action for all registered clients, if some clients generates exception it remove the /// registration. /// /// The action to invoke for all the clients /// The name of the logger public void InvokeOnAllClients(Action action, String loggerName) { ClientList unregisterClientList = null; foreach (IL4NClient client in this.GetEnumerator(loggerName)) { try { action(client); } catch (Exception) { //client must be unregistered. if (unregisterClientList == null) { unregisterClientList = new ClientList(); } unregisterClientList.Add(client); } } //now if I need to unregister some client i do it if (unregisterClientList != null) { unregisterClientList.ForEach(client => { //Remove from the global list clientsThatListenToAllLoggers.Remove(client); //Remove from all the specific logger list. foreach (KeyValuePair el in clients) { el.Value.Remove(client); } }); } } } }