feat: modify factory loading

Updating IDeviceFactory to resolve [FEATURE]-Refactor Plugin loading mechanism  #1065.
This change should be backwards-compatible with existing plugins that use the EssentialsPluginDeviceFactory<T> class,
as the interfaces are implemented by the various base classes.

In addition, the correct assembly name is now printed when a type is loaded.
This commit is contained in:
Andrew Welker 2025-07-04 16:07:45 -05:00 committed by Neil Dorin
parent 76759d35cc
commit 574e4dfb0f
8 changed files with 1543 additions and 1611 deletions

View file

@ -4,61 +4,54 @@ using System.Reflection;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials
namespace PepperDash.Essentials;
public class MobileControlFactory
{
/// <summary>
/// Factory class for the Mobile Control App Controller
/// </summary>
public class MobileControlFactory
public MobileControlFactory()
{
/// <summary>
/// Create an instance of the <see cref="MobileControlFactory"/> class.
/// </summary>
public MobileControlFactory()
var assembly = Assembly.GetExecutingAssembly();
PluginLoader.AddLoadedAssembly(assembly.GetName().Name, assembly);
var types = assembly.GetTypes().Where(t => typeof(IDeviceFactory).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract);
if (types == null)
{
var assembly = Assembly.GetExecutingAssembly();
PluginLoader.AddLoadedAssembly(assembly.GetName().Name, assembly);
var types = assembly.GetTypes().Where(t => typeof(IDeviceFactory).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract);
if (types == null)
{
return;
}
foreach (var type in types)
{
try
{
var factory = (IDeviceFactory)Activator.CreateInstance(type);
LoadDeviceFactories(factory);
}
catch (Exception ex)
{
Debug.LogMessage(ex, "Unable to load type '{type}' DeviceFactory: {factory}", null, type.Name);
}
}
return;
}
/// <summary>
/// Loads device factories from the specified plugin device factory and registers them for use.
/// </summary>
/// <remarks>This method retrieves metadata from the provided <paramref name="deviceFactory"/>, including
/// type names, descriptions, and configuration snippets, and registers the factory for each device type. The type
/// names are converted to lowercase for registration.</remarks>
/// <param name="deviceFactory">The plugin device factory that provides the device types, descriptions, and factory methods to be registered.</param>
private static void LoadDeviceFactories(IDeviceFactory deviceFactory)
foreach (var type in types)
{
foreach (var typeName in deviceFactory.TypeNames)
try
{
string description = (deviceFactory.FactoryType.GetCustomAttributes(typeof(DescriptionAttribute), true) is DescriptionAttribute[] descriptionAttribute && descriptionAttribute.Length > 0)
? descriptionAttribute[0].Description
: "No description available"; // Default value if no DescriptionAttribute is found
var factory = (IDeviceFactory)Activator.CreateInstance(type);
DeviceFactory.AddFactoryForType(typeName.ToLower(), description, deviceFactory.FactoryType, deviceFactory.BuildDevice);
LoadDeviceFactories(factory);
}
catch (Exception ex)
{
Debug.LogMessage(ex, "Unable to load type '{type}' DeviceFactory: {factory}", null, type.Name);
}
}
}
/// <summary>
/// Loads device factories from the specified plugin device factory and registers them for use.
/// </summary>
/// <remarks>This method retrieves metadata from the provided <paramref name="deviceFactory"/>, including
/// type names, descriptions, and configuration snippets, and registers the factory for each device type. The type
/// names are converted to lowercase for registration.</remarks>
/// <param name="deviceFactory">The plugin device factory that provides the device types, descriptions, and factory methods to be registered.</param>
private static void LoadDeviceFactories(IDeviceFactory deviceFactory)
{
foreach (var typeName in deviceFactory.TypeNames)
{
//Debug.LogMessage(LogEventLevel.Verbose, "Getting Description Attribute from class: '{0}'", typeof(T).FullName);
var descriptionAttribute = deviceFactory.FactoryType.GetCustomAttributes(typeof(DescriptionAttribute), true) as DescriptionAttribute[];
string description = descriptionAttribute[0].Description;
var snippetAttribute = deviceFactory.FactoryType.GetCustomAttributes(typeof(ConfigSnippetAttribute), true) as ConfigSnippetAttribute[];
Core.DeviceFactory.AddFactoryForType(typeName.ToLower(), description, deviceFactory.FactoryType, deviceFactory.BuildDevice);
}
}
}