Monday, February 09, 2009

Reflection on my own base classes - DNN 4 vs DNN 5 pain

So DotNetNuke5 is lovely... and so was DotNetNuke4....

However, someone has really upset me today by completely changing the base class functionality of AuthenticationConfigBase - which means that it's really hard to make an authentication module which will work in both DNN4 and in DNN5. Basically you get haunted by MissingMethodException's surrounding GetPortalSetting and PortalController.GetPortalSettingsDictionary.

To get around this, I had to reflect on the Config's own base class to find out what to use...

Here's the code.... I'm sure it could be more efficient - but it doesn't matter too much for where it is (it's not loaded very often)

Load settings:

        // Methods

        protected Config(int portalId)

            : base(portalId)

        {

            this._ApplicationKey = Null.NullString;

            this._Enabled = Null.NullBoolean;

            this._IncludeHelp = Null.NullBoolean;

            this._SecretKey = Null.NullString;

            this._LocationXDReceiver = Null.NullString;

 

            bool tryDnn4Methods = false;

            try

            {

                Dnn5LoadSettings(portalId);

            }

            catch (Exception /*e*/)

            {

                tryDnn4Methods = true;

            }

 

            if (!tryDnn4Methods)

                return;

 

            try

            {

                Dnn4LoadSettings();

            }

            catch (Exception e)

            {

                throw new ApplicationException("Cannot initialise Facebook Connect config", e);

            }

        }

 

        private void Dnn4LoadSettings()

        {

            if (!bool.TryParse(HackGetValueForDnn4("FacebookConnect_Enabled"), out this._Enabled))

                this._Enabled = false;

 

            this._ApplicationKey = HackGetValueForDnn4("FacebookConnect_ApplicationKey");

            this._SecretKey = HackGetValueForDnn4("FacebookConnect_SecretKey");

            if (!bool.TryParse(HackGetValueForDnn4("FacebookConnect_IncludeHelp"), out this._IncludeHelp))

                this._IncludeHelp = false;

            this._LocationXDReceiver = HackGetValueForDnn4("FacebookConnect_LocationXDReceiver");

        }

 

        private void Dnn5LoadSettings(int portalId)

        {

            this._Enabled = PortalController.GetPortalSettingAsBoolean("FacebookConnect_Enabled", portalId, Null.NullBoolean);

            this._ApplicationKey = PortalController.GetPortalSetting("FacebookConnect_ApplicationKey", portalId, Null.NullString);

            this._SecretKey = PortalController.GetPortalSetting("FacebookConnect_SecretKey", portalId, Null.NullString);

            this._IncludeHelp = PortalController.GetPortalSettingAsBoolean("FacebookConnect_IncludeHelp", portalId, Null.NullBoolean);

            this._LocationXDReceiver = PortalController.GetPortalSetting("FacebookConnect_LocationXDReceiver", portalId, Null.NullString);

        }

 

        private string HackGetValueForDnn4(string valueToGet)

        {

            Type type = this.GetType();

            System.Reflection.PropertyInfo info = type.GetProperty("ModuleSettings", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.SetProperty | System.Reflection.BindingFlags.Instance);

            if (info == null)

                throw new ApplicationException("Cannot initialise Facebook Connect - no ModuleSettings found");

 

            System.Collections.Hashtable hashTable = (System.Collections.Hashtable)info.GetValue(this, null);

            string value = (string)hashTable[valueToGet];

            if (value == null)

                value = string.Empty;

 

            return value;

        }

 

Save settings:

        internal void HackSetValueForDnn4(string valueToSet, string value)

        {

            ModuleController controller = new ModuleController();

            Type type = this.GetType();

            System.Reflection.PropertyInfo info = type.GetProperty("AuthenticationModuleID", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.SetProperty | System.Reflection.BindingFlags.Instance);

            if (info == null)

                throw new ApplicationException("Cannot initialise Facebook Connect - no ModuleSettings found");

 

            int authenticationModuleID = (int)info.GetValue(this, null);

 

            controller.UpdateModuleSetting(authenticationModuleID, valueToSet, value);

        }

 

        public static void UpdateConfig(Config config)

        {

            try

            {

                Dnn5UpdateSettings(config);

            }

            catch (Exception /*e*/)

            {

            }

 

            try

            {

                Dnn4UpdateSettings(config);

            }

            catch (Exception e)

            {

                // ignored

                //throw new ApplicationException("Cannot save Facebook Connect config", e);

            }

        }

 

        private static void Dnn4UpdateSettings(Config config)

        {

            config.HackSetValueForDnn4("FacebookConnect_Enabled", config.Enabled.ToString());

            config.HackSetValueForDnn4("FacebookConnect_ApplicationKey", config.ApplicationKey);

            config.HackSetValueForDnn4("FacebookConnect_SecretKey", config.SecretKey);

            config.HackSetValueForDnn4("FacebookConnect_IncludeHelp", config.IncludeHelp.ToString());

            config.HackSetValueForDnn4("FacebookConnect_LocationXDReceiver", config.LocationXDReceiver);

            ClearConfig(config.PortalID);

        }

 

        private static void Dnn5UpdateSettings(Config config)

        {

            PortalController.UpdatePortalSetting(config.PortalID, "FacebookConnect_Enabled", config.Enabled.ToString());

            PortalController.UpdatePortalSetting(config.PortalID, "FacebookConnect_ApplicationKey", config._ApplicationKey.ToString());

            PortalController.UpdatePortalSetting(config.PortalID, "FacebookConnect_SecretKey", config.SecretKey.ToString());

            PortalController.UpdatePortalSetting(config.PortalID, "FacebookConnect_IncludeHelp", config.IncludeHelp.ToString());

            PortalController.UpdatePortalSetting(config.PortalID, "FacebookConnect_LocationXDReceiver", config._LocationXDReceiver.ToString());

            ClearConfig(config.PortalID);

        }

 

No comments:

Post a Comment