jamesmontemagno / SettingsPlugin

Read and Write Settings Plugin for Xamarin and Windows
MIT License
324 stars 80 forks source link

Boke backwards compatibility when removing generic GetValueOrDefault #81

Closed fekberg closed 7 years ago

fekberg commented 7 years ago

Bug Information

Version Number of Plugin: 3.0.1 Device Tested On: iOS, Android Simulator Tested On: None Version of VS: VS for Mac (Latest Stable) Version of Xamarin: Latest Stable

The Problem

Using T GetValueOrDefault<T>(string key, T defaultValue = default(T)) in 2.5 which is no longer available breaks backwards compatibility.

Any reason this was removed?

jamesmontemagno commented 7 years ago

That is true! I explain in the readme and changelog, but essentially I never truly supported generics and developers were using the API wrong based on this leading to other bugs and assumptions. Now I lock down the API. Simply remove the and things should work just fine as I intended.

buzzware commented 6 years ago

My AppSettings class looks like this, and uses your 2.5 plugin :

    public class AppSettings : KeySettings {

        public AppSettings(ISettingsPersistence aPersistence=null) : base(aPersistence) {
        }

        public bool HasSetInitialTrackingSettings  { get { return GetValue<bool>(); } set { SetValue(value); } }
        public bool ManualTrackingEnabled  { get { return GetValue<bool>(); } set { SetValue(value); } }

I'm trying to upgrade to your latest, but it is almost impossible without a lot of boilerplate, or making your generic method public, or at least protected. You obviously appreciate the convenience of a generic method in your internal implementation.

It is impossible to call a non-generic method from a generic method, so I can't wrap your exposed methods with my own generic method.

Both your approaches here https://jamesmontemagno.github.io/SettingsPlugin/DataBindingToSettings.html are still quite verbose for the Count property. This is quite frustrating.

Please make protected or public generic access methods for GetValueOrDefaultInternal and friends.

buzzware commented 6 years ago

I solved it like this :


    public interface ISettingsPersistence {
        Decimal GetValueOrDefault(string key, Decimal defaultValue);
        bool GetValueOrDefault(string key, bool defaultValue);
        long GetValueOrDefault(string key, long defaultValue);
        string GetValueOrDefault(string key, string defaultValue);
        int GetValueOrDefault(string key, int defaultValue);
        float GetValueOrDefault(string key, float defaultValue);
        DateTime GetValueOrDefault(string key, DateTime defaultValue);
        Guid GetValueOrDefault(string key, Guid defaultValue);
        double GetValueOrDefault(string key, double defaultValue);
        bool AddOrUpdateValue(string key, Decimal value);
        bool AddOrUpdateValue(string key, bool value);
        bool AddOrUpdateValue(string key, long value);
        bool AddOrUpdateValue(string key, string value);
        bool AddOrUpdateValue(string key, int value);
        bool AddOrUpdateValue(string key, float value);
        bool AddOrUpdateValue(string key, DateTime value);
        bool AddOrUpdateValue(string key, Guid value);
        bool AddOrUpdateValue(string key, double value);
        void Remove(string key);
    }

    public abstract class KeySettings
    {
        protected readonly ISettingsPersistence _settings;
        public KeySettings(ISettingsPersistence aPersistence = null) {
            _settings = aPersistence;
        }

        private string GetKey(string key)
        {
            return string.Format("{0}{1}", GetType().FullName, key);
        }

        public Decimal GetValue(Decimal defaultValue,[CallerMemberName] string key = null) {
            return _settings!=null ? _settings.GetValueOrDefault(GetKey (key), defaultValue) : defaultValue;
        }

        public bool GetValue(bool defaultValue,[CallerMemberName] string key = null) {
            return _settings!=null ? _settings.GetValueOrDefault(GetKey (key), defaultValue) : defaultValue;
        }

        public long GetValue(long defaultValue,[CallerMemberName] string key = null) {
            return _settings!=null ? _settings.GetValueOrDefault(GetKey (key), defaultValue) : defaultValue;
        }

        public string GetValue(string defaultValue=null,[CallerMemberName] string key = null) {
            return _settings!=null ? _settings.GetValueOrDefault(GetKey (key), defaultValue) : defaultValue;
        }

        public int GetValue(int defaultValue,[CallerMemberName] string key = null) {
            return _settings!=null ? _settings.GetValueOrDefault(GetKey (key), defaultValue) : defaultValue;
        }

        public float GetValue(float defaultValue,[CallerMemberName] string key = null) {
            return _settings!=null ? _settings.GetValueOrDefault(GetKey (key), defaultValue) : defaultValue;
        }

        public DateTime GetValue(DateTime defaultValue,[CallerMemberName] string key = null) {
            return _settings!=null ? _settings.GetValueOrDefault(GetKey (key), defaultValue) : defaultValue;
        }

        public Guid GetValue(Guid defaultValue,[CallerMemberName] string key = null) {
            return _settings!=null ? _settings.GetValueOrDefault(GetKey (key), defaultValue) : defaultValue;
        }

        public double GetValue(double defaultValue,[CallerMemberName] string key = null) {
            return _settings!=null ? _settings.GetValueOrDefault(GetKey (key), defaultValue) : defaultValue;
        }

        public void SetValue(Decimal value, [CallerMemberName] string key = null) {
            _settings?.AddOrUpdateValue(GetKey(key),value);
        }

        public void SetValue(bool value, [CallerMemberName] string key = null) {
            _settings?.AddOrUpdateValue(GetKey(key),value);
        }

        public void SetValue(long value, [CallerMemberName] string key = null) {
            _settings?.AddOrUpdateValue(GetKey(key),value);
        }

        public void SetValue(string value, [CallerMemberName] string key = null) {
            _settings?.AddOrUpdateValue(GetKey(key),value);
        }

        public void SetValue(int value, [CallerMemberName] string key = null) {
            _settings?.AddOrUpdateValue(GetKey(key),value);
        }

        public void SetValue(float value, [CallerMemberName] string key = null) {
            _settings?.AddOrUpdateValue(GetKey(key),value);
        }

        public void SetValue(DateTime value, [CallerMemberName] string key = null) {
            _settings?.AddOrUpdateValue(GetKey(key),value);
        }

        public void SetValue(Guid value, [CallerMemberName] string key = null) {
            _settings?.AddOrUpdateValue(GetKey(key),value);
        }

        public void SetValue(double value, [CallerMemberName] string key = null) {
            _settings?.AddOrUpdateValue(GetKey(key),value);
        }
}

    public class CrossSettingsWrapper : SettingsImplementation, ISettingsPersistence {

        public decimal GetValueOrDefault(string key, decimal defaultValue) {
            return base.GetValueOrDefault(key, defaultValue, null);
        }

        public bool GetValueOrDefault(string key, bool defaultValue) {
            return base.GetValueOrDefault(key, defaultValue, null);
        }

        public long GetValueOrDefault(string key, long defaultValue) {
            return base.GetValueOrDefault(key, defaultValue, null);
        }

        public string GetValueOrDefault(string key, string defaultValue) {
            return base.GetValueOrDefault(key, defaultValue, null);
        }

        public int GetValueOrDefault(string key, int defaultValue) {
            return base.GetValueOrDefault(key, defaultValue, null);
        }

        public float GetValueOrDefault(string key, float defaultValue) {
            return base.GetValueOrDefault(key, defaultValue, null);
        }

        public DateTime GetValueOrDefault(string key, DateTime defaultValue) {
            return base.GetValueOrDefault(key, defaultValue, null);
        }

        public Guid GetValueOrDefault(string key, Guid defaultValue) {
            return base.GetValueOrDefault(key, defaultValue, null);
        }

        public double GetValueOrDefault(string key, double defaultValue) {
            return base.GetValueOrDefault(key, defaultValue, null);
        }

        public bool AddOrUpdateValue(string key, decimal value) {
            return base.AddOrUpdateValue(key, value, null);
        }

        public bool AddOrUpdateValue(string key, bool value) {
            return base.AddOrUpdateValue(key, value, null);
        }

        public bool AddOrUpdateValue(string key, long value) {
            return base.AddOrUpdateValue(key, value, null);
        }

        public bool AddOrUpdateValue(string key, string value) {
            return base.AddOrUpdateValue(key, value, null);
        }

        public bool AddOrUpdateValue(string key, int value) {
            return base.AddOrUpdateValue(key, value, null);
        }

        public bool AddOrUpdateValue(string key, float value) {
            return base.AddOrUpdateValue(key, value, null);
        }

        public bool AddOrUpdateValue(string key, DateTime value) {
            return base.AddOrUpdateValue(key, value, null);
        }

        public bool AddOrUpdateValue(string key, Guid value) {
            return base.AddOrUpdateValue(key, value, null);
        }

        public bool AddOrUpdateValue(string key, double value) {
            return base.AddOrUpdateValue(key, value, null);
        }

        public void Remove(string key) {
            base.Remove(key,null);
        }
    }

    public class AppSettings : KeySettings {

        public AppSettings(ISettingsPersistence aPersistence=null) : base(aPersistence) {
        }

        public bool HasSetInitialTrackingSettings  { get { return GetValue(false); } set { SetValue(value); } }
        public bool ManualTrackingEnabled  { get { return GetValue(false); } set { SetValue(value); } }
:
:
:

var settingsPersistence = new CrossSettingsWrapper();
var appSettings = new AppSettings(settingsPersistence);