public static void AddUser <T>(UrlSubscription <T> user) { //attempt to get type subscription SubscriptionsByType subscriptionsByUser; SubscriptionsByType.TryGetValue(typeof(T), out subscriptionsByUser); //if unable to get attempt to add if (subscriptionsByUser == null) { subscriptionsByUser = new SubscriptionsByType() { SubscriptionType = typeof(T) }; //add new type subscription var wasAdded = SubscriptionsByType.TryAdd(typeof(T), subscriptionsByUser); //if add failed then likely another thread was adding at the same time, try again if (!wasAdded) { AddUser <T>(user); return; } } //attempt to get user subscription SubscriptionsByUser subscriptionsByUrl; subscriptionsByUser.SubscriptionsByUser.TryGetValue(user.ConnectionId, out subscriptionsByUrl); //if unable to get attempt to add if (subscriptionsByUrl == null) { subscriptionsByUrl = new SubscriptionsByUser() { SubscriptionType = typeof(T) }; //add new type subscription var wasAdded = subscriptionsByUser.SubscriptionsByUser.TryAdd(user.ConnectionId, subscriptionsByUrl); //if add failed then likely another thread was adding at the same time, try again if (!wasAdded) { AddUser <T>(user); return; } } //add or update value with new value subscriptionsByUrl.SubscriptionsByUrl.AddOrUpdate(user.Url, user, (key, oldValue) => oldValue = user); }
// DO NOT REMOVE, ACCESSED BY STRING, I KNOW IT'S NASTY public static List <UserSubscriptionResult> GetSubscribed <T>(SubscriptionsByType subscriptionsByUser, List <ChangedObject> values) { var results = new List <UserSubscriptionResult>(); foreach (var user in subscriptionsByUser.SubscriptionsByUser) { if (user.Value == null) { continue; } var userResults = new UserSubscriptionResult { ConnectionId = user.Key }; foreach (var url in user.Value.SubscriptionsByUrl) { if (url.Value == null) { continue; } IURLSubscription interfaceSubscription = url.Value; UrlSubscription <T> typedSubscription = (UrlSubscription <T>)interfaceSubscription; foreach (var value in values) { var typedObject = (T)value.Object; if (typedSubscription.Query == null || typedSubscription.Query.Invoke(typedObject)) { var newUrl = new UrlSubscriptionResults { Url = url.Key }; newUrl.Data.Add(value); userResults.Urls.Add(newUrl); } } } if (userResults.Urls.Any()) { results.Add(userResults); } } return(results); }