示例#1
0
 public void RecordCalculatedResults(string k1, string k2, decimal pr)
 {
     if (calculatedResults.ContainsKey(k1))
     {
         var innerDictionary = calculatedResults[k1];
         if (innerDictionary.ContainsKey(k2))
         {
             throw new NotSupportedException("This pattern expects only one entry per k1k2 pair");
         }
         else
         {
             //ToDo: Better understanding/handling of exceptions here
             try
             {
                 innerDictionary.Add(k2, pr);
             }
             catch { new Exception($"adding {pr} to {k1}'s innerDictionary keyed by {k2} failed"); }
         }
     }
     else
     {
         var innerDictionary = new ConcurrentObservableDictionary <string, decimal>();
         try { innerDictionary.Add(k2, pr); } catch { new Exception($"adding {pr} to the new innerDictionary keyed by {k2} failed"); }
         try { calculatedResults.Add(k1, innerDictionary); } catch { new Exception($"adding the new innerDictionary to calculatedResults keyed by {k1} failed"); }
     };
 }
示例#2
0
        public void RecordR(string k1, string k2, decimal pr)
        {
            if (ResultsCOD.ContainsKey(k1))
            {
                var innerCOD = ResultsCOD[k1];
                if (innerCOD.ContainsKey(k2))
                {
                    throw new NotSupportedException("This pattern expects only one entry per k1k2 pair");
                }
                else
                {
                    //ToDo: Better understanding/handling of exceptions here
                    try { innerCOD.Add(k2, pr); } catch { new Exception($"adding {pr} to {k1}'s innerDictionary keyed by {k2} failed"); }
                }
            }
            else
            {
                var innerCOD = new ConcurrentObservableDictionary <string, decimal>();
                if (this.onResultsNestedCODCollectionChanged != null)
                {
                    innerCOD.CollectionChanged += this.onResultsNestedCODCollectionChanged;
                }

                if (this.onResultsNestedCODPropertyChanged != null)
                {
                    innerCOD.PropertyChanged += this.onResultsNestedCODPropertyChanged;
                }

                try { innerCOD.Add(k2, pr); } catch { new Exception($"adding {pr} to the new innerDictionary keyed by {k2} failed"); }
                try { ResultsCOD.Add(k1, innerCOD); } catch { new Exception($"adding the new innerDictionary to cODR keyed by {k1} failed"); }
            };
        }
示例#3
0
        public void ConcurrentObservableDictionaryTest()
        {
            ConcurrentObservableDictionary <int, string> dict = new ConcurrentObservableDictionary <int, string>();
            var times = 0;

            dict.CollectionChanged += delegate
            {
                times++;
            };

            dict.Add(1, "foo");
            dict.Add(2, "moo");
            dict.Add(3, "boo");

            dict.AddOrReplace(1, "boo");
            dict.Remove(dict.First(x => x.Value == "moo"));

            Assert.True(dict.Values.All(x => x == "boo"));
            Assert.Equal(5, times);
        }
示例#4
0
        public void ConcurrentObservableDictionaryTest()
        {
            ConcurrentObservableDictionary <int, string> dict = new ConcurrentObservableDictionary <int, string>();

            _times = 0;
            dict.CollectionChanged += Dict_CollectionChanged;

            try
            {
                dict.Add(1, "foo");
                dict.Add(2, "moo");
                dict.Add(3, "boo");

                dict.AddOrReplace(1, "boo");
                dict.Remove(dict.First(x => x.Value == "moo"));

                Assert.DoesNotContain(dict.Values, x => x != "boo");
                Assert.Equal(5, _times);
            }
            finally
            {
                dict.CollectionChanged -= Dict_CollectionChanged;
            }
        }
示例#5
0
        public void ConcurrentObservableDictionarySerializationTest()
        {
            var serializer = new BinaryFormatter();
            var stream     = new MemoryStream();
            var collection = new ConcurrentObservableDictionary <string, int>();

            for (int i = 0; i < 10; i++)
            {
                collection.Add("TestItem" + (i + 1).ToString(), i);
            }
            serializer.Serialize(stream, collection);
            stream.Position = 0;
            collection      = serializer.Deserialize(stream) as ConcurrentObservableDictionary <string, int>;
            for (int i = 0; i < 10; i++)
            {
                Assert.AreEqual(i, collection["TestItem" + (i + 1).ToString()]);
            }
        }
示例#6
0
        /// <summary>
        /// Defines the value of a property of this class.
        /// This action triggers the <see cref="PropertyChanged"/> event, unless <see cref="AllowRaiseEvent"/> is set top false.
        /// </summary>
        /// <param name="key">The name of the property</param>
        /// <param name="value">The value of the property</param>
        public virtual void SetValue(string key, object value)
        {
            key = key.ToLower();

            object old = null;

            if (!_values.ContainsKey(key))
            {
                _values.Add(key, value);
            }
            else
            {
                old          = _values[key];
                _values[key] = value;
            }

            if (old != value)
            {
                OnPropertyChanged(key, old, value);
            }
        }
        public void TestManyOperations()
        {
            // Create some random, but unique items
            // Use a fixed seed for consistency in results
            Random        random       = new Random(1);
            HashSet <int> baseItemsSet = new HashSet <int>();

            while (baseItemsSet.Count < 1_100_000)
            {
                baseItemsSet.Add(random.Next());
            }

            // Create 2 collections, 1 to test, and 1 to compare against
            var testCollection = new ConcurrentObservableDictionary <string, string>();
            var list           = new List <KeyValuePair <string, string> >();

            // Create 1,000,000 items to add and insert
            var itemsToAdd =
                baseItemsSet
                .Take(1_000_000)
                .Select(x => Swordfish.NET.Collections.KeyValuePair.Create($"Key {x}", $"Value {x}"))
                .ToList();

            // Create 100,000 items to insert
            var itemsToInsert =
                baseItemsSet
                .Skip(1_000_000)
                .Take(100_000)
                .Select(x => Swordfish.NET.Collections.KeyValuePair.Create($"Insert Key {x}", $"Insert Value {x}"))
                .ToList();

            // Create items to remove
            var itemsToRemove =
                itemsToInsert
                .Take(1000)
                .ToList();

            foreach (var item in itemsToAdd)
            {
                testCollection.Add(item.Key, item.Value);
                list.Add(item);
            }

            // Check items are equal count
            Assert.IsTrue(list.Count == testCollection.Count, "Added Items correct count");

            // Check items are equal order
            var allEqualAfterAdd =
                list
                .Zip(testCollection, (a, b) => (a.Key == b.Key) && (a.Value == b.Value))
                .All(a => a);

            Assert.IsTrue(allEqualAfterAdd, "Added items correct order");

            // Test inserting items

            int insertIndex = itemsToInsert.Count + 100;

            foreach (var item in itemsToInsert)
            {
                // We have the function but it's there for other reasons
                testCollection.Insert(insertIndex, item);

                list.Insert(insertIndex, item);

                insertIndex--;
            }

            // Check items are equal count
            Assert.IsTrue(list.Count == testCollection.Count, "Items correct count after inserting");

            // Check items are equal order
            var allEqualAfterInsert =
                list
                .Zip(testCollection, (a, b) => (a.Key == b.Key) && (a.Value == b.Value))
                .All(a => a);

            Assert.IsTrue(allEqualAfterAdd, "Items correct order after insert");

            // Test removing items

            foreach (var item in itemsToRemove)
            {
                testCollection.Remove(item.Key);
                list.Remove(item);
            }

            // Check items are equal count
            Assert.IsTrue(list.Count == testCollection.Count, "Items correct count after removing");

            // Check items are equal order
            var allEqualAfterRemove =
                list
                .Zip(testCollection, (a, b) => (a.Key == b.Key) && (a.Value == b.Value))
                .All(a => a);

            Assert.IsTrue(allEqualAfterRemove, "Items correct order after removing");

            // Test contains

            var containsAll = list
                              .All(kv => testCollection.Contains(kv));

            Assert.IsTrue(containsAll, "Contains all the items is true");

            var containsNone = itemsToRemove
                               .Any(kv => testCollection.ContainsKey(kv.Key));

            Assert.IsFalse(containsNone, "Contains any of the removed items is false");

            // Test removing at

            int removeAtIndex = list.Count - 30;

            while (removeAtIndex >= 0 && list.Count > 0)
            {
                list.RemoveAt(removeAtIndex);
                testCollection.RemoveAt(removeAtIndex);
                removeAtIndex -= 30;
            }

            // Check items are equal count
            Assert.IsTrue(list.Count == testCollection.Count, "Items correct count after removing at index");

            // Check items are equal order
            var allEqualAfterRemoveAt =
                list
                .Zip(testCollection, (a, b) => (a.Key == b.Key) && (a.Value == b.Value))
                .All(a => a);

            Assert.IsTrue(allEqualAfterRemoveAt, "Items correct order after removing at index");
        }
        public void Configure(IAppHost appHost)
        {
            Log.Debug("starting RealEstateServicesPlugin.Configure");

            // Populate this Plugin's Application Configuration Settings
            // Location of the files will depend on running as LifeCycle Production/QA/Dev as well as Debug and Release settings
            var pluginAppSettings = new MultiAppSettingsBuilder()
                                    // Command line flags have highest priority
                                    // next in priority are  Environment variables
                                    //.AddEnvironmentalVariables()
                                    // next in priority are Configuration settings in a text file relative to the current working directory at the point in time when this method executes.
                                    .AddTextFile(pluginSettingsTextFileName)
                                    // Builtin (compiled in) have the lowest priority
                                    .AddDictionarySettings(DefaultConfiguration.Configuration())
                                    .Build();

            // Key names in the cache for Configuration settings for a Plugin consist of the namespace and the string .Config
            // Key names in the appSettings of a Plugin for Configuration settings may or may not have the prefix
            // Compare the two lists of Configuration setting keys...

            // create a copy of the keys from AppSettings ensuring all are prefixed with the namespace and .Config
            var configKeyPrefix           = myNamespace + ".Config.";
            var lengthConfigKeyPrefix     = configKeyPrefix.Length;
            var appSettingsConfigKeys     = pluginAppSettings.GetAllKeys();
            var fullAppSettingsConfigKeys = appSettingsConfigKeys.Select(x => x.IndexOf(configKeyPrefix) >= 0? x: configKeyPrefix + x);

            // Get this namespaces configuration settings from the cache
            var cacheClient     = appHost.GetContainer().Resolve <ICacheClient>();
            var cacheConfigKeys = cacheClient.GetKeysStartingWith(configKeyPrefix);

            // Compare the configuration retrieved from the cache with the configuration from the built-in defaults, the text files, and the environment variables
            // If the cache is missing a ConfigKey, update the cache with the ConfigKey and its value from the appSettings
            var excludedConfigKeys   = new HashSet <string>(cacheConfigKeys);
            var additionalConfigKeys = fullAppSettingsConfigKeys.Where(ck => !excludedConfigKeys.Contains(ck));

            foreach (var ck in additionalConfigKeys)
            {
                cacheClient.Set <string>(ck, pluginAppSettings.GetString(ck.Substring(lengthConfigKeyPrefix)));
            }
            // If both the cache and the appSettings have the same ConfigKey, and the same value, do nothing
            // If both the cache and the appSettings have the same ConfigKey, and the values are different,
            // If the cache has a ConfigKey and the appSettings does not have that ConfigKey
            // Set a flag indicating the need to dialog with the user to resolve the cache vs. appSettings discrepancies
            bool configurationsMatch = true; // (appSettingsConfigkeys.Count == cacheConfigkeys.Count) ;


            // Populate this Plugin's Gateways
            // Location of the files will depend on running as LifeCycle Production/QA/Dev as well as Debug and Release settings
            var pluginGateways = new MultiGatewaysBuilder()
                                 // Command line flags have highest priority
                                 // next in priority are  Environment variables
                                 //.AddEnvironmentalVariables()
                                 // next in priority are Configuration settings in a text file relative to the current working directory at the point in time when this method executes.
                                 //.AddTextFile(pluginGatewaysTextFileName)
                                 // Builtin (compiled in) have the lowest priority
                                 //.AddDictionarySettings(DefaultGateways.Configuration())
                                 .Build();



            // Create a Gateways collection from the txt file
            ConcurrentObservableDictionary <string, IGateway> gateways = new ConcurrentObservableDictionary <string, IGateway>();

            gateways.Add("GoogleMapsGeoCoding", new GatewayBuilder().Build());
            // Create the Plugin's data structure. There should only be a single instance.
            // Every Property matching a ConfigKey gets/sets the value of the matching ConfigKey in the cache
            // ConfigKey Properties do not have to be set in the constructor because the cache was setup before calling the constructor


            RealEstateServicesData RealEstateServicesData = new RealEstateServicesData(appHost, new ConcurrentObservableDictionary <string, decimal>(), onPluginRootCollectionChanged, onPluginRootPropertyChanged);

            // copy the most recent configuration settings to the Data
            // hmm should be a way to make sure the Data has a Property for each configuration setting, and to populate the initial Data with the cache value
            RealEstateServicesData.GoogleAPIKeyEncrypted   = cacheClient.Get <string>(configKeyPrefix + "GoogleAPIKeyEncrypted");
            RealEstateServicesData.HomeAwayAPIKeyEncrypted = cacheClient.Get <string>(configKeyPrefix + "HomeAwayAPIKeyEncrypted");
            RealEstateServicesData.HomeAway_API_URI        = cacheClient.Get <string>(configKeyPrefix + "HomeAway_API_URI");
            RealEstateServicesData.Google_API_URI          = cacheClient.Get <string>(configKeyPrefix + "Google_API_URI");
            RealEstateServicesData.UriHomeAway_API_URI     = cacheClient.Get <Uri>(configKeyPrefix + "UriHomeAway_API_URI");
            RealEstateServicesData.UriGoogle_API_URI       = cacheClient.Get <Uri>(configKeyPrefix + "UriGoogle_API_URI");

            // and pass the Plugin's data structure to the container so it will be available to every other module and services
            appHost.GetContainer()
            .Register <RealEstateServicesData>(x => RealEstateServicesData);



            // ToDo: enable the mechanisms that monitors each GUI-specific data sensor, and start them running
        }