Gets clean build

This commit is contained in:
Neil Dorin
2023-10-25 10:31:42 -06:00
parent 14b6900460
commit 48a5bd64a4
12 changed files with 271 additions and 125 deletions

View File

@@ -121,6 +121,41 @@ namespace PepperDash.Essentials.Core
#endregion
}
public abstract class ProcessorExtensionDeviceFactory<T> : IProcessorExtensionDeviceFactory where T: EssentialsDevice
{
#region IProcessorExtensionDeviceFactory Members
/// <summary>
/// A list of strings that can be used in the type property of a DeviceConfig object to build an instance of this device
/// </summary>
public List<string> TypeNames { get; protected set; }
/// <summary>
/// Loads an item to the ProcessorExtensionDeviceFactory.ProcessorExtensionFactoryMethods dictionary for each entry in the TypeNames list
/// </summary>
public void LoadFactories()
{
foreach (var typeName in TypeNames)
{
//Debug.Console(2, "Getting Description Attribute from class: '{0}'", typeof(T).FullName);
var descriptionAttribute = typeof(T).GetCustomAttributes(typeof(DescriptionAttribute), true) as DescriptionAttribute[];
string description = descriptionAttribute[0].Description;
var snippetAttribute = typeof(T).GetCustomAttributes(typeof(ConfigSnippetAttribute), true) as ConfigSnippetAttribute[];
ProcessorExtensionDeviceFactory.AddFactoryForType(typeName.ToLower(), description, typeof(T), BuildDevice);
}
}
/// <summary>
/// The method that will build the device
/// </summary>
/// <param name="dc">The device config</param>
/// <returns>An instance of the device</returns>
public abstract EssentialsDevice BuildDevice(DeviceConfig dc);
#endregion
}
/// <summary>
/// Devices the basic needs for a Device Factory
/// </summary>

View File

@@ -1,20 +1,11 @@
extern alias Full;
using Crestron.SimplSharp.Reflection;
using Full.Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core.Config;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.GeneralIO;
using Crestron.SimplSharp.Reflection;
using PepperDash.Core;
using Full.Newtonsoft.Json.Linq;
using Full.Newtonsoft.Json;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.CrestronIO;
using PepperDash.Essentials.Core.Touchpanels;
namespace PepperDash.Essentials.Core
{

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PepperDash.Essentials.Core
{
public interface IProcessorExtensionDeviceFactory
{
/// <summary>
/// Loads all the extension factories to the ProcessorExtensionDeviceFactory
/// </summary>
void LoadFactories();
}
}

View File

@@ -0,0 +1,155 @@
extern alias Full;
using Crestron.SimplSharp.Reflection;
using Full.Newtonsoft.Json.Linq;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core.Config;
using System;
using System.Collections.Generic;
using System.Linq;
namespace PepperDash.Essentials.Core
{
public class ProcessorExtensionDeviceFactory
{
public ProcessorExtensionDeviceFactory() {
var assy = Assembly.GetExecutingAssembly();
PluginLoader.SetEssentialsAssembly(assy.GetName().Name, assy);
var extensions = assy.GetTypes().Where(ct => typeof(IProcessorExtensionDeviceFactory)
.IsAssignableFrom(ct) && !ct.IsInterface && !ct.IsAbstract);
if (extensions != null )
{
foreach ( var extension in extensions )
{
try
{
var factory = (IProcessorExtensionDeviceFactory)Crestron.SimplSharp.Reflection.Activator.CreateInstance(extension);
factory.LoadFactories();
}
catch( Exception e )
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to load extension device: '{1}' ProcessorExtensionDeviceFactory: {0}", e, extension.Name);
}
}
}
}
/// <summary>
/// A dictionary of factory methods, keyed by config types, added by plugins.
/// These methods are looked up and called by GetDevice in this class.
/// </summary>
static Dictionary<string, DeviceFactoryWrapper> ProcessorExtensionFactoryMethods =
new Dictionary<string, DeviceFactoryWrapper>(StringComparer.OrdinalIgnoreCase);
/// <summary>
/// Adds a plugin factory method
/// </summary>
/// <param name="dc"></param>
/// <returns></returns>
public static void AddFactoryForType(string extensionName, Func<DeviceConfig, IKeyed> method)
{
//Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
ProcessorExtensionDeviceFactory.ProcessorExtensionFactoryMethods.Add(extensionName, new DeviceFactoryWrapper() { FactoryMethod = method });
}
public static void AddFactoryForType(string extensionName, string description, CType cType, Func<DeviceConfig, IKeyed> method)
{
//Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
if (ProcessorExtensionFactoryMethods.ContainsKey(extensionName))
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to add extension device: '{0}'. Already exists in ProcessorExtensionDeviceFactory", extensionName);
return;
}
var wrapper = new DeviceFactoryWrapper() { CType = cType, Description = description, FactoryMethod = method };
ProcessorExtensionDeviceFactory.ProcessorExtensionFactoryMethods.Add(extensionName, wrapper);
}
private static void CheckForSecrets(IEnumerable<Full.Newtonsoft.Json.Linq.JProperty> obj)
{
foreach (var prop in obj.Where(prop => prop.Value as Full.Newtonsoft.Json.Linq.JObject != null))
{
if (prop.Name.ToLower() == "secret")
{
var secret = GetSecret(prop.Children().First().ToObject<SecretsPropertiesConfig>());
//var secret = GetSecret(JsonConvert.DeserializeObject<SecretsPropertiesConfig>(prop.Children().First().ToString()));
prop.Parent.Replace(secret);
}
var recurseProp = prop.Value as Full.Newtonsoft.Json.Linq.JObject;
if (recurseProp == null) return;
CheckForSecrets(recurseProp.Properties());
}
}
private static string GetSecret(SecretsPropertiesConfig data)
{
var secretProvider = SecretsManager.GetSecretProviderByKey(data.Provider);
if (secretProvider == null) return null;
var secret = secretProvider.GetSecret(data.Key);
if (secret != null) return (string)secret.Value;
Debug.Console(1,
"Unable to retrieve secret {0}{1} - Make sure you've added it to the secrets provider",
data.Provider, data.Key);
return String.Empty;
}
/// <summary>
/// The factory method for processor extension devices. Also iterates the Factory methods that have
/// been loaded from plugins
/// </summary>
/// <param name="dc"></param>
/// <returns></returns>
public static IKeyed GetExtensionDevice(DeviceConfig dc)
{
try
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading '{0}' from Essentials Core", dc.Type);
var localDc = new DeviceConfig(dc);
var key = localDc.Key;
var name = localDc.Name;
var type = localDc.Type;
var properties = localDc.Properties;
//var propRecurse = properties;
var typeName = localDc.Type.ToLower();
var jObject = properties as Full.Newtonsoft.Json.Linq.JObject;
if (jObject != null)
{
var jProp = jObject.Properties();
CheckForSecrets(jProp);
}
Debug.Console(2, "typeName = {0}", typeName);
// Check for types that have been added by plugin dlls.
return !ProcessorExtensionFactoryMethods.ContainsKey(typeName) ? null : ProcessorExtensionFactoryMethods[typeName].FactoryMethod(localDc);
}
catch (Exception ex)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Exception occurred while creating device {0}: {1}", dc.Key, ex.Message);
Debug.Console(2, "{0}", ex.StackTrace);
if (ex.InnerException == null)
{
return null;
}
Debug.Console(0, Debug.ErrorLogLevel.Error, "Inner exception while creating device {0}: {1}", dc.Key,
ex.InnerException.Message);
Debug.Console(2, "{0}", ex.InnerException.StackTrace);
return null;
}
}
}
}

View File

@@ -27,7 +27,7 @@
<Reference Include="System.Net.Http" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Crestron.SimplSharp.SDK.ProgramLibrary" Version="2.19.36" />
<PackageReference Include="Crestron.SimplSharp.SDK.ProgramLibrary" Version="2.20.31" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2">
<Aliases>Full</Aliases>
</PackageReference>