using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using InABox.Core; using Syncfusion.Windows.Shared; namespace InABox.DynamicGrid { public static class DynamicEditorControlFactory { private static Dictionary>? _editors; private static Dictionary> GetEditors() { if(_editors is null) { _editors = []; foreach(var type in CoreUtils.TypeList(AppDomain.CurrentDomain.GetAssemblies(), x => x.IsClass && !x.IsAbstract && !x.IsGenericType)) { Type? valueType = null; Type? editor = null; if(type.GetSuperclassDefinition(typeof(DynamicEditorControl<,>)) is Type editorClass) { valueType = editorClass.GenericTypeArguments[0]; editor = editorClass.GenericTypeArguments[1]; } else if(type.GetSuperclassDefinition(typeof(DynamicEnclosedEditorControl<,>)) is Type enclosedEditorClass) { valueType = enclosedEditorClass.GenericTypeArguments[0]; editor = enclosedEditorClass.GenericTypeArguments[1]; } if (editor is not null && valueType is not null && (editor == typeof(IBaseEditor) || editor.HasInterface())) { _editors.GetValueOrAdd(editor).Add((valueType, type)); } } } return _editors; } private static bool GetControlType(Type editorType, Type valueType, [NotNullWhen(true)] out Type? TControl) { var controls = GetEditors().Where(x => editorType == x.Key || editorType.IsAssignableTo(x.Key)); Type? editType = null; List<(Type valueType, Type editor)>? tControls = null; TControl = null; foreach(var control in controls) { if(control.Key == editorType) { tControls = control.Value; break; } if(TControl is null || editType!.IsAssignableTo(control.Key)) { (editType, tControls) = control; } } if (tControls is null) return false; Type? _valueType = null; foreach(var control in tControls) { if(control.valueType == valueType) { TControl = control.editor; return true; } if(valueType.IsAssignableTo(control.valueType) && (_valueType is null || _valueType.IsAssignableTo(control.valueType))) { (_valueType, TControl) = control; } } return TControl is not null; } public static BaseDynamicEditorControl? CreateControl(BaseEditor editor, Type valueType, IDynamicEditorHost host) { if (GetControlType(editor.GetType(), valueType, out var TControl)) { var result = Activator.CreateInstance(TControl) as BaseDynamicEditorControl; if (result != null) { result.ValueType = valueType; result.Host = host; result.EditorDefinition = editor; } return result; } return null; } } }