using System.Reflection; namespace Pilz.Plugins.Advanced; public class PluginFeatureController { // D e l e g a t e s public delegate void PluginFeatureEventHandler(PluginFeatureController controller, PluginFeature feature); // S t a t i c E v e n t s /// /// Fires when a new has been registred. /// public static event PluginFeatureEventHandler? OnPluginFeatureReistred; /// /// Fires when a has been unregistred. /// public static event PluginFeatureEventHandler? OnPluginFeatureUnregistred; // S t a t i c M e m b e r s protected static readonly string nameGetFeatures = $"{nameof(IPluginFeaturesProvider.GetFeatures)}"; protected static readonly string nameGetFeaturesExplicit = $"{typeof(IPluginFeaturesProvider).FullName}.{nameof(IPluginFeaturesProvider.GetFeatures)}"; protected static readonly string nameInstance = $"get_{nameof(IPluginFeatureProvider.Instance)}"; protected static readonly string nameInstnaceExplicit = $"{typeof(IPluginFeaturesProvider).FullName}.get_{nameof(IPluginFeatureProvider.Instance)}"; /// /// The default public instance that can be used by plugins and the interface providing software. /// public static PluginFeatureController Instance { get; private set; } = new(); // I n s t a n c e M e m e b e r s private readonly HashSet features = []; /// /// A wrapper of all registred instances. /// public FeatureController Features { get; init; } /// /// A wrapper for all registred instances. /// public ModuleController Modules { get; init; } /// /// A wrapper for all registred instances. /// public FunctionController Functions { get; init; } public PluginFeatureController() { Features = new(this); Functions = new(this); Modules = new(this); } /// /// Registers all features found in the currently executing Assembly via , and . /// Note:
Explicit implementations of can not be detected. For this case just implement instead.
///
public void RegisterAllOwn() { RegisterAll(Assembly.GetCallingAssembly()); } /// /// Registers all features found in the given via , and . /// Note:
Explicit implementations of can not be detected. For this case just implement instead.
///
/// public void RegisterAll(Assembly[] assemblies) { foreach (var assembly in assemblies) RegisterAll(assembly); } /// /// Registers all features found in the given via , and . /// Note:
Explicit implementations of can not be detected. For this case just implement instead.
///
/// public void RegisterAll(Assembly assembly) { RegisterAll(assembly.GetTypes()); } /// /// Registers all features found from the given via , and . /// Note:
Explicit implementations of can not be detected. For this case just implement instead.
///
/// public void RegisterAll(Type[] types) { foreach (var type in types) RegisterAll(type); } /// /// Registers all features found from the given via , and . /// Note:
Explicit implementations of can not be detected. For this case just implement instead.
///
/// public void RegisterAll(Type type) { if (type.IsAssignableTo(typeof(IPluginFeaturesProvider))) { var methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); var method = methods.FirstOrDefault(n => n.Name == nameGetFeaturesExplicit || n.Name == nameGetFeatures); if (method != null && method.Invoke(null, null) is PluginFeature[] features) { foreach (var feature in features) Register(feature); } } else if (type.IsAssignableTo(typeof(IPluginFeatureProvider))) { var methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); var method = methods.FirstOrDefault(n => n.Name == nameInstnaceExplicit || n.Name == nameInstance); if (method != null && method.Invoke(null, null) is PluginFeature feature) Register(feature); } } /// /// Registers a feature via the given or . /// public void Register() where TProvider : IPluginFeatureProvider { Register(TProvider.Instance); } /// /// Registers all features via the given . /// public void RegisterAll() where TProvider : IPluginFeaturesProvider { foreach (var feature in TProvider.GetFeatures()) Register(feature); } /// /// Registers the given feature. /// /// public void Register(PluginFeature module) { if (!features.Contains(module)) { features.Add(module); OnPluginFeatureReistred?.Invoke(this, module); } } /// /// Unregisters the given feature. /// /// public void Unregister(PluginFeature module) { features.Remove(module); OnPluginFeatureUnregistred?.Invoke(this, module); } public class FeatureController(PluginFeatureController controller) { protected readonly PluginFeatureController controller = controller; public virtual IEnumerable GetAll() { return controller.features.ToArray(); } public virtual IEnumerable Get(string featureType) { return controller.features.Where(n => n.Type == featureType); } public virtual PluginFeature? GetFirst(string featureType) { return controller.features.FirstOrDefault(n => n.Type == featureType); } public virtual PluginFeature? GetByIdentifier(string fullIdentifier) { return controller.features.FirstOrDefault(n => n.FullIdentifier == fullIdentifier); } public virtual PluginFeature? GetByIdentifier(string featureType, string identifier) { return controller.features.FirstOrDefault(n => n.Type == featureType && n.Identifier == identifier); } } public class FeatureController(PluginFeatureController controller) : FeatureController(controller) where T : PluginFeature { public override IEnumerable GetAll() { return controller.features.OfType(); } public override IEnumerable Get(string moduleType) { return GetAll().Where(n => n.Type == moduleType); } public override T? GetFirst(string moduleType) { return base.GetFirst(moduleType) as T; } public override T? GetByIdentifier(string fullIdentifier) { return base.GetByIdentifier(fullIdentifier) as T; } public override T? GetByIdentifier(string featureType, string identifier) { return base.GetByIdentifier(featureType, identifier) as T; } } public class ModuleController(PluginFeatureController controller) : FeatureController(controller) { } public class FunctionController(PluginFeatureController controller) : FeatureController(controller) { public void ExecuteAll(string functionType) { foreach (var function in Get(functionType)) function.Execute(); } public void ExecuteAll(string functionType, params object?[]? @params) { foreach (var function in Get(functionType)) function.Execute(@params); } public void ExecuteAll(string functionType, PluginFunctionParameter @params) { foreach (var function in Get(functionType)) function.Execute(@params); } public IEnumerable ExcuteAndGetResults(string functionType) { return Get(functionType).Select(n => n.Execute()); } public IEnumerable ExcuteAndGetResults(string functionType, params object?[]? @params) { return Get(functionType).Select(n => n.Execute(@params)); } public IEnumerable ExcuteAndGetResults(string functionType, PluginFunctionParameter @params) { return Get(functionType).Select(n => n.Execute(@params)); } } }