From a93ded8c7940374491be549507bb3c5d172acc42 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 23 Apr 2020 14:59:54 -0600 Subject: [PATCH] New device loading methodology working via reflection --- PepperDashEssentials/ControlSystem.cs | 50 ++------ PepperDashEssentials/Factory/DeviceFactory.cs | 39 +++--- .../Factory/UiDeviceFactory.cs | 36 ------ .../PepperDashEssentials.csproj | 1 - .../Inputs/GenericDigitalInputDevice.cs | 2 +- .../Crestron IO/Relay/GenericRelayDevice.cs | 1 - .../Factory/DeviceFactory.cs | 48 ++++---- .../Plugins/PluginLoader.cs | 22 +++- .../Essentials_DM/Config/DeviceFactory.cs | 43 ++++--- .../Display/DeviceFactory.cs | 33 ----- .../Essentials Devices Common.csproj | 1 - .../Factory/DeviceFactory.cs | 113 ++++-------------- 12 files changed, 121 insertions(+), 268 deletions(-) delete mode 100644 PepperDashEssentials/Factory/UiDeviceFactory.cs delete mode 100644 essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/DeviceFactory.cs diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index e4d4cbc0..f0cdc9d5 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -86,47 +86,6 @@ namespace PepperDash.Essentials GoWithLoad(); } - /// - /// Instantiates each of the device factories to load their device types - /// - void LoadDeviceTypesFromFactories() - { - PluginLoader.AddProgramAssemblies(); - - - foreach (var assembly in PluginLoader.LoadedAssemblies) - { - if (!assembly.Name.Contains("Essentials")) - { - continue; - } - else - { - var assy = assembly.Assembly; - var types = assy.GetTypes(); - - if (types != null) - { - foreach (var type in types) - { - try - { - if (typeof(IDeviceFactory).IsAssignableFrom(type)) - { - var factory = (IDeviceFactory)Crestron.SimplSharp.Reflection.Activator.CreateInstance(type); - factory.LoadTypeFactories(); - } - } - catch (Exception e) - { - Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to load DeviceFactory: {0}", e); - } - } - } - } - } - } - /// /// Determines if the program is running on a processor (appliance) or server (VC-4). /// @@ -202,10 +161,15 @@ namespace PepperDash.Essentials public void GoWithLoad() { try - { + { Debug.SetDoNotLoadOnNextBoot(false); - LoadDeviceTypesFromFactories(); + PluginLoader.AddProgramAssemblies(); + + new Core.DeviceFactory(); + new Devices.Common.DeviceFactory(); + new DM.DeviceFactory(); + new DeviceFactory(); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials load from configuration"); diff --git a/PepperDashEssentials/Factory/DeviceFactory.cs b/PepperDashEssentials/Factory/DeviceFactory.cs index 944a9b2f..5b15f28c 100644 --- a/PepperDashEssentials/Factory/DeviceFactory.cs +++ b/PepperDashEssentials/Factory/DeviceFactory.cs @@ -4,6 +4,7 @@ using System.Linq; using Crestron.SimplSharp; using Crestron.SimplSharp.CrestronIO; using Crestron.SimplSharpPro; +using Crestron.SimplSharp.Reflection; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -18,26 +19,30 @@ namespace PepperDash.Essentials /// Responsible for loading all of the device types for this library /// public class DeviceFactory - { + { + public DeviceFactory() { - var ampFactory = new AmplifierFactory() as IDeviceFactory; - ampFactory.LoadTypeFactories(); + var assy = Assembly.GetExecutingAssembly(); + PluginLoader.SetEssentialsAssembly(assy.GetName().Name, assy); - var mockDisplayFactory = new MockDisplayFactory() as IDeviceFactory; - mockDisplayFactory.LoadTypeFactories(); + var types = assy.GetTypes().Where(ct => typeof(IDeviceFactory).IsAssignableFrom(ct) && !ct.IsInterface && !ct.IsAbstract); - var consoleCommMockFactroy = new ConsoleCommMockDeviceFactory() as IDeviceFactory; - consoleCommMockFactroy.LoadTypeFactories(); - - var mcSystemControllerFactory = new MobileControlSystemControllerFactory() as IDeviceFactory; - mcSystemControllerFactory.LoadTypeFactories(); - - var mcSIMPLRoomBridgeFactory = new MobileControlSIMPLRoomBridgeFactory() as IDeviceFactory; - mcSIMPLRoomBridgeFactory.LoadTypeFactories(); - - var roomOnToDefSourceWhenOcc = new RoomOnToDefaultSourceWhenOccupiedFactory() as IDeviceFactory; - roomOnToDefSourceWhenOcc.LoadTypeFactories(); + if (types != null) + { + foreach (var type in types) + { + try + { + var factory = (IDeviceFactory)Crestron.SimplSharp.Reflection.Activator.CreateInstance(type); + factory.LoadTypeFactories(); + } + catch (Exception e) + { + Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to load type: '{1}' DeviceFactory: {0}", e, type.Name); + } + } + } } - } + } } diff --git a/PepperDashEssentials/Factory/UiDeviceFactory.cs b/PepperDashEssentials/Factory/UiDeviceFactory.cs deleted file mode 100644 index fad8026f..00000000 --- a/PepperDashEssentials/Factory/UiDeviceFactory.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro; -using Crestron.SimplSharpPro.DeviceSupport; -using Crestron.SimplSharpPro.UI; - -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using PepperDash.Core; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.Config; -using PepperDash.Essentials.Core.PageManagers; -using PepperDash.Essentials.DM.Endpoints.DGEs; - - -namespace PepperDash.Essentials -{ - /// - /// Responsible for loading all of the UI device types for this library - /// - public class UiDeviceFactory - { - public UiDeviceFactory() - { - var dgeControllerFactory = new DgeControllerFactory() as IDeviceFactory; - dgeControllerFactory.LoadTypeFactories(); - - var essentialsTouchpanelControllerFactory = new EssentialsTouchpanelControllerFactory() as IDeviceFactory; - essentialsTouchpanelControllerFactory.LoadTypeFactories(); - } - - } -} \ No newline at end of file diff --git a/PepperDashEssentials/PepperDashEssentials.csproj b/PepperDashEssentials/PepperDashEssentials.csproj index 62cae03f..6c606273 100644 --- a/PepperDashEssentials/PepperDashEssentials.csproj +++ b/PepperDashEssentials/PepperDashEssentials.csproj @@ -151,7 +151,6 @@ - diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Inputs/GenericDigitalInputDevice.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Inputs/GenericDigitalInputDevice.cs index 33cb0ae6..3d3383e9 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Inputs/GenericDigitalInputDevice.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Inputs/GenericDigitalInputDevice.cs @@ -9,7 +9,7 @@ using Newtonsoft.Json; using PepperDash.Core; using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.Config; -using PepperDash_Essentials_Core.Devices; + namespace PepperDash.Essentials.Core.CrestronIO { diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Relay/GenericRelayDevice.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Relay/GenericRelayDevice.cs index 3e3b0576..aac9de44 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Relay/GenericRelayDevice.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Relay/GenericRelayDevice.cs @@ -9,7 +9,6 @@ using Newtonsoft.Json; using PepperDash.Core; using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.Config; -using PepperDash_Essentials_Core.Devices; namespace PepperDash.Essentials.Core.CrestronIO { diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs index 4e12ab05..1904867d 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs @@ -29,6 +29,30 @@ namespace PepperDash.Essentials.Core public class DeviceFactory { + public DeviceFactory() + { + var assy = Assembly.GetExecutingAssembly(); + PluginLoader.SetEssentialsAssembly(assy.GetName().Name, assy); + + var types = assy.GetTypes().Where(ct => typeof(IDeviceFactory).IsAssignableFrom(ct) && !ct.IsInterface && !ct.IsAbstract); + + if (types != null) + { + foreach (var type in types) + { + try + { + var factory = (IDeviceFactory)Crestron.SimplSharp.Reflection.Activator.CreateInstance(type); + factory.LoadTypeFactories(); + } + catch (Exception e) + { + Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to load type: '{1}' DeviceFactory: {0}", e, type.Name); + } + } + } + } + /// /// A dictionary of factory methods, keyed by config types, added by plugins. /// These methods are looked up and called by GetDevice in this class. @@ -122,28 +146,4 @@ namespace PepperDash.Essentials.Core } } } - - /// - /// Responsible for loading all of the device types for this library - /// - public class CoreDeviceFactory - { - public CoreDeviceFactory() - { - Debug.Console(1, "Essentials.Core Factory Adding Types..."); - - //cast to IDeviceFactory isn't explicitly required here...but will be when instantiating using reflection, which I'm assuming is the next step - var genCommFactory = new GenericCommFactory() as IDeviceFactory; - genCommFactory.LoadTypeFactories(); - - var c2nRthsFactory = new C2nRthsControllerFactory() as IDeviceFactory; - c2nRthsFactory.LoadTypeFactories(); - - var statusSignFactory = new StatusSignControllerFactory() as IDeviceFactory; - statusSignFactory.LoadTypeFactories(); - - var cenIoControllerFactory = new CenIoDigIn104ControllerFactory() as IDeviceFactory; - cenIoControllerFactory.LoadTypeFactories(); - } - } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs index d32e9efa..5c66ab8f 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs @@ -68,25 +68,21 @@ namespace PepperDash.Essentials case ("PepperDashEssentials.dll"): { version = Global.AssemblyVersion; - assembly = Assembly.GetExecutingAssembly(); break; } - case ("PepperDash_Essential_Core.dll"): + case ("PepperDash_Essentials_Core.dll"): { version = Global.AssemblyVersion; - assembly = System.Reflection break; } case ("PepperDash_Essentials_DM.dll"): { version = Global.AssemblyVersion; - assembly = Assembly.GetExecutingAssembly(); break; } case ("Essentials Devices Common.dll"): { version = Global.AssemblyVersion; - assembly = Assembly.GetExecutingAssembly(); break; } case ("PepperDash_Core.dll"): @@ -110,6 +106,17 @@ namespace PepperDash.Essentials } } + + public static void SetEssentialsAssembly(string name, Assembly assembly) + { + var loadedAssembly = LoadedAssemblies.FirstOrDefault(la => la.Name.Equals(name)); + + if (loadedAssembly != null) + { + loadedAssembly.SetAssembly(assembly); + } + } + /// /// Loads an assembly via Reflection and adds it to the list of loaded assemblies /// @@ -503,5 +510,10 @@ namespace PepperDash.Essentials Version = version; Assembly = assembly; } + + public void SetAssembly(Assembly assembly) + { + Assembly = assembly; + } } } \ No newline at end of file diff --git a/essentials-framework/Essentials DM/Essentials_DM/Config/DeviceFactory.cs b/essentials-framework/Essentials DM/Essentials_DM/Config/DeviceFactory.cs index 6e10ae61..5c532ac5 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Config/DeviceFactory.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Config/DeviceFactory.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Collections.Generic; using Crestron.SimplSharp; using Crestron.SimplSharp.CrestronIO; @@ -6,6 +7,7 @@ using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.AirMedia; using Crestron.SimplSharpPro.UI; +using Crestron.SimplSharp.Reflection; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -20,25 +22,30 @@ namespace PepperDash.Essentials.DM /// /// Responsible for loading the type factories for this library /// - public class DmDeviceFactory - { - public DmDeviceFactory() + public class DeviceFactory + { + public DeviceFactory() { - Debug.Console(1, "Essentials.DM Factory Adding Types..."); + var assy = Assembly.GetExecutingAssembly(); + PluginLoader.SetEssentialsAssembly(assy.GetName().Name, assy); + + var types = assy.GetTypes().Where(ct => typeof(IDeviceFactory).IsAssignableFrom(ct) && !ct.IsInterface && !ct.IsAbstract); - var dmChassisFactory = new DmChassisControllerFactory() as IDeviceFactory; - dmChassisFactory.LoadTypeFactories(); - - var dmTxFactory = new DmTxControllerFactory() as IDeviceFactory; - dmTxFactory.LoadTypeFactories(); - - var dmRxFactory = new DmRmcControllerFactory() as IDeviceFactory; - dmRxFactory.LoadTypeFactories(); - - var hdMdFactory = new HdMdxxxCEControllerFactory() as IDeviceFactory; - hdMdFactory.LoadTypeFactories(); + if (types != null) + { + foreach (var type in types) + { + try + { + var factory = (IDeviceFactory)Crestron.SimplSharp.Reflection.Activator.CreateInstance(type); + factory.LoadTypeFactories(); + } + catch (Exception e) + { + Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to load type: '{1}' DeviceFactory: {0}", e, type.Name); + } + } + } } - - } - + } } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/DeviceFactory.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/DeviceFactory.cs deleted file mode 100644 index 099e1204..00000000 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/DeviceFactory.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Collections.Generic; -using Crestron.SimplSharp; -using Crestron.SimplSharp.CrestronIO; -using Crestron.SimplSharpPro; - -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using PepperDash.Core; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.Config; - -namespace PepperDash.Essentials.Devices.Displays -{ - public class DisplayDeviceFactory - { - public DisplayDeviceFactory() - { - var necFactory = new NecPSXMDisplayFactory() as IDeviceFactory; - necFactory.LoadTypeFactories(); - - var panasonicThFactory = new PanasonicThDisplayFactory() as IDeviceFactory; - panasonicThFactory.LoadTypeFactories(); - - var samsungMdcFactory = new SamsungMDCFactory() as IDeviceFactory; - samsungMdcFactory.LoadTypeFactories(); - - var avocorFactory = new AvocorDisplayFactory() as IDeviceFactory; - avocorFactory.LoadTypeFactories(); - } - - } -} \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj index 6585b074..147ace5b 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj @@ -132,7 +132,6 @@ - diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Factory/DeviceFactory.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Factory/DeviceFactory.cs index 8904b8c3..c860d0cb 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Factory/DeviceFactory.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Factory/DeviceFactory.cs @@ -1,9 +1,11 @@ using System; +using System.Linq; using System.Collections.Generic; using Crestron.SimplSharp; using Crestron.SimplSharp.CrestronIO; using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.GeneralIO; +using Crestron.SimplSharp.Reflection; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -20,96 +22,31 @@ using PepperDash.Essentials.Devices.Common.Environment; namespace PepperDash.Essentials.Devices.Common { - public class DeviceFactory - { + public class DeviceFactory + { + public DeviceFactory() { - var appleTVFactory = new AppleTVFactory() as IDeviceFactory; - appleTVFactory.LoadTypeFactories(); + var assy = Assembly.GetExecutingAssembly(); + PluginLoader.SetEssentialsAssembly(assy.GetName().Name, assy); + + var types = assy.GetTypes().Where(ct => typeof(IDeviceFactory).IsAssignableFrom(ct) && !ct.IsInterface && !ct.IsAbstract); - var analogWayLCFactory = new AnalogWayLiveCoreFactory() as IDeviceFactory; - analogWayLCFactory.LoadTypeFactories(); - - var basicIrDisplayFactory = new BasicIrDisplayFactory() as IDeviceFactory; - basicIrDisplayFactory.LoadTypeFactories(); - - var biampTesiraFactory = new BiampTesiraForteDspFactory() as IDeviceFactory; - biampTesiraFactory.LoadTypeFactories(); - - var cameraViscaFactory = new Cameras.CameraViscaFactory() as IDeviceFactory; - cameraViscaFactory.LoadTypeFactories(); - - var cenRfGwFactory = new CenRfgwControllerFactory() as IDeviceFactory; - cenRfGwFactory.LoadTypeFactories(); - - var irBlurayFactory = new IRBlurayBaseFactory() as IDeviceFactory; - irBlurayFactory.LoadTypeFactories(); - - var digitalLoggerFactory = new DigitalLoggerFactory() as IDeviceFactory; - digitalLoggerFactory.LoadTypeFactories(); - - var genericAudioOutFactory = new GenericAudioOutWithVolumeFactory() as IDeviceFactory; - genericAudioOutFactory.LoadTypeFactories(); - - var genericSourceFactory = new GenericSourceFactory() as IDeviceFactory; - genericSourceFactory.LoadTypeFactories(); - - var inRoomPcFactory = new Core.Devices.InRoomPcFactory() as IDeviceFactory; - inRoomPcFactory.LoadTypeFactories(); - - var laptopFactory = new Core.Devices.LaptopFactory() as IDeviceFactory; - laptopFactory.LoadTypeFactories(); - - var blueJeansPcFactory = new SoftCodec.BlueJeansPcFactory() as IDeviceFactory; - blueJeansPcFactory.LoadTypeFactories(); - - var mockAcFactory = new AudioCodec.MockACFactory() as IDeviceFactory; - mockAcFactory.LoadTypeFactories(); - - var mockVcFactory = new VideoCodec.MockVCFactory() as IDeviceFactory; - mockVcFactory.LoadTypeFactories(); - - var ciscoCodecFactory = new VideoCodec.Cisco.CiscoSparkCodecFactory() as IDeviceFactory; - ciscoCodecFactory.LoadTypeFactories(); - - var zoomRoomFactory = new VideoCodec.ZoomRoom.ZoomRoomFactory() as IDeviceFactory; - zoomRoomFactory.LoadTypeFactories(); - - var digitalInputFactory = new GenericDigitalInputDeviceFactory() as IDeviceFactory; - digitalInputFactory.LoadTypeFactories(); - - var relayFactory = new GenericRelayDeviceFactory() as IDeviceFactory; - relayFactory.LoadTypeFactories(); - - var micPrivacyFactory = new Core.Privacy.MicrophonePrivacyControllerFactory() as IDeviceFactory; - micPrivacyFactory.LoadTypeFactories(); - - var rokuFactory = new Roku2Factory() as IDeviceFactory; - rokuFactory.LoadTypeFactories(); - - var setTopBoxFactory = new IRSetTopBoxBaseFactory() as IDeviceFactory; - setTopBoxFactory.LoadTypeFactories(); - - var tvOneCorioFactory = new TVOneCorioFactory() as IDeviceFactory; - tvOneCorioFactory.LoadTypeFactories(); - - var glsOccSensorBaseFactory = new GlsOccupancySensorBaseControllerFactory() as IDeviceFactory; - glsOccSensorBaseFactory.LoadTypeFactories(); - - var glsOdtOccSensorFactory = new GlsOdtOccupancySensorControllerFactory() as IDeviceFactory; - glsOdtOccSensorFactory.LoadTypeFactories(); - - var lutronQuantumFactory = new Environment.Lutron.LutronQuantumAreaFactory() as IDeviceFactory; - lutronQuantumFactory.LoadTypeFactories(); - - var din8sw8ControllerFactory = new Environment.Lighting.Din8sw8ControllerFactory() as IDeviceFactory; - din8sw8ControllerFactory.LoadTypeFactories(); - - var shadeControllerFactory = new Core.Shades.ShadeControllerFactory() as IDeviceFactory; - shadeControllerFactory.LoadTypeFactories(); - - var relayControlledShadeFactory = new Environment.Somfy.RelayControlledShadeFactory() as IDeviceFactory; - relayControlledShadeFactory.LoadTypeFactories(); + if (types != null) + { + foreach (var type in types) + { + try + { + var factory = (IDeviceFactory)Crestron.SimplSharp.Reflection.Activator.CreateInstance(type); + factory.LoadTypeFactories(); + } + catch (Exception e) + { + Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to load type: '{1}' DeviceFactory: {0}", e, type.Name); + } + } + } } - } + } } \ No newline at end of file