SkiaComponentRegistry
How component types are registered, queried and instantiated across the framework
SkiaComponentRegistry is a static catalog of component types. It is the single source of truth that the palette, templates, serialization and palette drops all read from. It stores no instances — only AssemblyClassDefinition metadata and factory helpers.
Table of Contents
What It Stores
The registry keeps a List<AssemblyClassDefinition> (exposed as LoadedComponents). Each entry describes one component type:
| Member | Type | Meaning |
|---|---|---|
className | string | Class name; the palette converts it to a display label. |
dllname | string | Assembly that provides the type. |
GuidID | string | Stable identifier for lookups. |
type | Type | Resolved CLR type used for instantiation. |
Methods | List<MethodsClass> | Optional command methods surfaced as palette children. |
Duplicates are rejected on insert by comparing GuidID, or className plus dllname. Re-registering the same type is therefore a no-op rather than an error.
Registration
Three shapes are available depending on how many entries you have:
// One at a time
SkiaComponentRegistry.AddComponent(definition);
// A batch (skips duplicates individually)
SkiaComponentRegistry.AddComponents(definitions);
// Replace everything (used when re-scanning a plugin folder)
SkiaComponentRegistry.SetComponents(definitions);
In practice you rarely call these directly. The supported paths are:
- Extension SDK —
ISkiaExtension.GetComponentTypes()declares types andISkiaExtensionContext.RegisterComponent(type, category, displayName)registers them;SkiaExtensionHostperforms discovery. See Extension SDK. - Assembly scanning — hosts that already use the shared BeepDM
AssemblyHandlerfeed the discovered definitions intoSetComponents/AddComponents. - Tests and tools — construct
AssemblyClassDefinitionvalues directly and callClear()between runs.
Queries
| Member | Returns |
|---|---|
GetComponents() | All registered definitions. |
GetComponentsOrdered() | The same list ordered for display; the palette uses this. |
GetComponentByName(className) | The definition for a class name, or null. |
GetComponentByGuid(guid) | The definition for a stable id, or null. |
GetComponentsByAssembly(assemblyName) | Everything provided by one assembly. |
GetComponentsByType(typeName) | Everything matching a type name. |
GetComponentsWithMethods() | Only components that expose command methods. |
GetComponentsWithVisualProperties() | Components that carry designer/visual metadata. |
GetComponentsByCapabilities(hasLocalDB, isDataSource, inMemory) | Capability-filtered subsets. |
GetAvailableNamespaces() | Distinct namespaces, useful for grouping in tools. |
IsComponentRegistered(className) | Fast existence check. |
Clear() | Empties the registry (tests, host shutdown). |
Instantiation
Two overloads create instances: from a definition or from a class name. Both use the parameterless constructor, so every component type must have one.
// From a palette item (ComponentItem wraps the definition)
var component = SkiaComponentRegistry.CreateComponentInstance(args.Component.ClassDefinition);
// From a name
var node = SkiaComponentRegistry.CreateComponentInstance("ProcessNode");
if (node != null)
{
node.X = 120;
node.Y = 80;
drawingManager.AddComponent(node);
}
Creation is deliberately dumb: it constructs the type and returns it. Positioning, naming, undo registration and parenting belong to the caller (the host control does all four when you drop from the palette).
Who Reads It
| Consumer | Usage |
|---|---|
ComponentPalette | LoadComponentsFromRegistry() groups GetComponentsOrdered() into categories. |
DrawingManager templates | GetTemplates() and LoadTemplate(dto) build diagrams from built-in DTOs. |
| Serialization | LoadFromDto resolves ComponentDto.Type with Type.GetType(); a missing type is skipped, not fatal. |
| Extension host | Registers extension components and commands during Initialize. |
| Tests | Whole-surface sweeps enumerate the registry to exercise every component type. |
Registry vs. Extension SDK
The registry is storage; the extension SDK is the supported way to fill it. Prefer implementing ISkiaExtension over calling AddComponent directly so packages can be installed, versioned and uninstalled through the marketplace.