internal MjolnirConfigurationObserver(MjolnirConfiguration currentConfig,
                                       Func <MjolnirConfiguration, T> propertyToCheck, Action <T> onChange)
 {
     _expression   = propertyToCheck;
     _currentValue = _expression(currentConfig);
     _onChange     = onChange;
 }
        public void OnNext(MjolnirConfiguration value)
        {
            var newValue   = _expression(value);
            var hasChanged = !Equals(_currentValue, newValue);

            if (!hasChanged)
            {
                return;
            }

            try
            {
                // Invoke onChange action to act apon config change.
                _onChange(newValue);
            }
            catch (Exception)
            {
                // Even if onChange implementation returns exception we still want to process other changes. Exception
                // here should not affect observable implementation.
            }
            finally
            {
                _currentValue = newValue;
            }
        }
        internal static IDisposable OnConfigurationChanged <T>(this MjolnirConfiguration currentConfig, Func <MjolnirConfiguration, T> propertyToCheck, Action <T> onChangeAction)
        {
            var observer = new MjolnirConfigurationObserver <T>(currentConfig, propertyToCheck, onChangeAction);

            return(currentConfig.Subscribe(observer));
        }